Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tokunami/962df26616fa93bfdc6c to your computer and use it in GitHub Desktop.
Save tokunami/962df26616fa93bfdc6c to your computer and use it in GitHub Desktop.
$(function(){
var socket = io.connect();
//接続確認
socket.on('connect',function(){
console.log('connected.');
socket.on('count', function(data){
$('#count').text(data);
});
//メッセージを受信
socket.on('msg push', function(msg){
$('#img').attr("src", msg.text);
$('#imgtitle').html(msg.text);
$('#list').prepend($("<dt>" + new Date() + "</dt><p>" + msg.name + ":" + msg.text + "</p><hr>"));
});
});
//メッセージを送信
$('#comment_form').on('submit',function(){
var name = $('#name').val();
var text = $('#text').val();
if(text && name){
socket.emit('msg post',{name: name, text: text});
$('#text').val('');
};
});
socket.on("roomList", function(roomList){
$("#list-box").text("");
if(roomList){
Object.keys(roomList).forEach(function(rname){
console.log(rname + "," + roomList[rname] + "人");
$("#list-box").append("ルーム『"+ rname + "』に" + roomList[rname] +"人います<br>");
});
}
});
//サーバーに入るルーム名を送信
$('#room_form').on('submit', function(){
var name = $("#enter").val();
socket.emit("enter", name);
});
});
doctype html
html
head
meta(charset="utf-8")
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
script(type='text/javascript', src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js')
script(type='text/javascript', src='/socket.io/socket.io.js')
script(type='text/javascript', src='/javascripts/client.js')
body
h1= title
p 現在の閲覧者数は
span#count
人です
div#list-box
br
form#room_form(action="javascript:void(0);" method="get" onsubmit="return false;")
input#enter(type="text" name="enter")
input(type="submit" value="ルームへ")
form#comment_form(action="javascript:void(0);" autocomplete="off")
p 名前:
input#name(type="text")
p メッセージ:
input#text(type="text")
input(type="submit" value="送信")
hr
image#img(src='/images/noimage.jpg')
p#imgtitle
hr
dl#list

Node.js + express + socket.io で画像を返すチャットルーム(ver. 2)

コードレビューを受けて修正しました。

コードレビュー以降に変更した部分は以下です。

  1. 取得したroom名からスラッシュをとる(正規表現)
  2. clientがどのroomにもjoinしていないときは、全員に送信するようにする
  3. 切断時の処理
  4. clientが複数roomにjoinできないようにする

1. 取得したroom名からスラッシュをとる(正規表現)

room = room.replace(/\//, '');
  • 「/」を「/」に置換する
  • Javascriptの正規表現は奥が深そうでした。ちゃんと調べます。

2. clientがどのroomにもjoinしていないときは、全員に送信するようにする

//clientがデフォルト以外のどのroomにもjoinしていないときは、全員に送信
if(!roomsn[1] && roomsn[0] ===''){
  io.sockets.emit('msg push', {name: msg.name, text: msg.text});
}

3. 切断時の処理

socket.on('disconnect', function(){
  //接続人数を-1して送信
  count--;
  io.sockets.emit('count', count);

  //clientが接続しているroom名を取得
  var rooms = io.sockets.manager.roomClients[socket.id];

  //keyを取り出す
  var roomsn = Object.keys(rooms);

  roomsn.forEach(function(room){
    if(room !==''){
      //スラッシュをとる
      room = room.replace(/\//,'');
      //人数を-1
      roomList[room]--;

      //人数が0人以下になったらroomListから削除
      if(roomList[room] <= 0){
        delete roomList[room];
      }
    }
  });

  //roomListの更新
  io.sockets.emit('roomList', roomList);

});
  • clientが接続しているroom名を取得→keyを取り出す→空でなければスラッシュをとる→そのroomの人数を-1
  • 人数を-1して0以下になったらroomListから削除
4. clientが複数roomにjoinできないようにする
socket.on("enter", function(rname){

  //clientがjoinしているroom名を取得する
  var rooms = io.sockets.manager.roomClients[socket.id];

  //keyを取り出す
  var roomsn = Object.keys(rooms);

  roomsn.forEach(function(room){
  
    //default('')以外に空でないroomsn要素があるとき
    if(roomsn[1] && room !==''){

      //スラッシュをとる
      room = room.replace(/\//, '');

      //そのroomから退室する
      socket.leave(room);
      roomList[room]--;

      //人数が0人以下になったらroomListから削除
      if(roomList[room] <= 0){
        delete roomList[room];
      }
    }
  });

  //roomListを確認(略)

  //roomにjoin(略)

  //roomListを更新(略)

});
  • 3の切断とほぼ同じ処理。
現在はroomの入退室を繰り返しても、過去にpostしたメッセージは画面にそのまま残る仕様。roomがかわるとメッセージ画面も更新するようにしてみる予定。
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, io = require('socket.io');
var fs = require('fs');
var app = express();
var server = http.createServer(app);
var io = io.listen(server);
var IMAGE_DIR = path.join(__dirname, 'public', 'images');
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', function(req,res){
res.render('index',{
title: 'ChatRoom'
});
});
app.get('/:msg', function(req, res){
if(typeof req.params.msg === 'undefined'){
res.send(400);
return;
}
fs.readFile(path.join(IMAGE_DIR , req.params.msg + '.jpg'), function(err, data){
if(err){
console.error(err);
res.send(500);
return;
}
console.log(req.params.msg);
res.set('Content-Type', 'image/jpeg');
res.send(data);
});
});
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
var count = 0;
var roomList = new Object();
io.sockets.on('connection', function(socket) {
console.log("connected");
console.log(roomList);
count++;
io.sockets.emit('count', count);
socket.on("enter", function(rname){
//clientがjoinしているroom名を取得する
var rooms = io.sockets.manager.roomClients[socket.id];
//keyを取り出す
var roomsn = Object.keys(rooms);
roomsn.forEach(function(room){
//default('')以外に空でないroomsn要素があるとき
if(roomsn[1] && room !==''){
//スラッシュをとる
room = room.replace(/\//, '');
//そのroomから退室する
socket.leave(room);
roomList[room]--;
//人数が0人以下になったらroomListから削除
if(roomList[room] <= 0){
delete roomList[room];
console.log(room + 'は削除されました');
}
}
});
//roomListを確認
if(!roomList[rname]){
roomList[rname] = 1;
}else{
roomList[rname]++;
}
//roomにjoin
socket.join(rname);
//roomListを更新
io.sockets.emit("roomList",roomList);
});
socket.on('msg post', function(msg) {
//clientがjoinしているroom名を取得する
var rooms = io.sockets.manager.roomClients[socket.id];
//keyを取り出す
var roomsn = Object.keys(rooms);
//clientがデフォルト以外のどのroomにもjoinしていないときは、全員に送信
if(!roomsn[1] && roomsn[0] ===''){
io.sockets.emit('msg push', {name: msg.name, text: msg.text});
}else{
roomsn.forEach(function (room){
//clientがroomにjoinしているときは、そのroomに送信
if(room !==''){
//スラッシュをとる
room = room.replace(/\//, '');
io.sockets.to(room).emit('msg push', {name: msg.name, text: msg.text});
}
});
}
});
//切断した時の処理
socket.on('disconnect', function(){
//接続人数を-1して送信
count--;
io.sockets.emit('count', count);
//clientが接続しているroom名を取得
var rooms = io.sockets.manager.roomClients[socket.id];
//keyを取り出す
var roomsn = Object.keys(rooms);
//roomの人数を-1
roomsn.forEach(function(room){
if(room !==''){
//スラッシュをとる
room = room.replace(/\//,'');
//人数を-1
roomList[room]--;
//人数が0人以下になったらroomListから削除
if(roomList[room] <= 0){
delete roomList[room];
}
}
});
//roomListの更新
io.sockets.emit('roomList', roomList);
});
});
@itoatsushi
Copy link

githubはつかえるようになりました?
でしたら、使い方の練習も兼ねてこのソフトウェアはgithub上にリポジトリを作って管理してみましょう。

@tokunami
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment