基于socket.io+express实现多房间聊天

socket.io简介

Socket.IO是一个开源的WebSocket库,它通过Node.js实现WebSocket服务端,同时也提供客户端JS库。Socket.IO支持以事件为基础的实时双向通讯,它可以工作在任何平台、浏览器或移动设备。

Socket.IO支持4种协议:WebSocket、htmlfile、xhr-polling、jsonp-polling,它会自动根据浏览器选择适合的通讯方式,从而让开发者可以聚焦到功能的实现而不是平台的兼容性,同时Socket.IO具有不错的稳定性和性能。

多房间聊天

socket.io提供rooms和namespace的API

用rooms的API就可以实现多房间聊天了,总结出来无外乎就是:join/leave room 和 say to room

// say to room
io.to('some room').emit('some event'):
io.in('some room').emit('some event'):

代码 github 新建文件夹chatapp-demo chatapp-demo/package.json

执行 npm install

服务端代码

增加文件 chatapp-demo/app.js

var app = express();
var server = require('http').Server(app);
app.use(express.static(path.join(dirname,'public')));
app.set('views',path.join(
dirname,'views'));
app.set('view engine','hbs');

// 创建socket服务
var socketIO = IO(server);
// 房间用户名单
var roomInfo = {};

socketIO.on('connection',function (socket) {
// 获取请求建立socket连接的url
// 如: http://localhost:3000/room/room_1,roomID为room_1
var url = socket.request.headers.referer;
var splited = url.split('/');
var roomID = splited[splited.length - 1]; // 获取房间ID
var user = '';

socket.on('join',function (userName) {
user = userName;

// 将用户昵称加入房间名单中
if (!roomInfo[roomID]) {
roomInfo[roomID] = [];
}
roomInfo[roomID].push(user);

socket.join(roomID); // 加入房间
// 通知房间内人员
socketIO.to(roomID).emit('sys',user + '加入了房间',roomInfo[roomID]);
console.log(user + '加入了' + roomID);
});

socket.on('leave',function () {
socket.emit('disconnect');
});

socket.on('disconnect',function () {
// 从房间名单中移除
var index = roomInfo[roomID].indexOf(user);
if (index !== -1) {
roomInfo[roomID].splice(index,1);
}

socket.leave(roomID); // 退出房间
socketIO.to(roomID).emit('sys',user + '退出了房间',roomInfo[roomID]);
console.log(user + '退出了' + roomID);
});

// 接收用户消息,发送相应的房间
socket.on('message',function (msg) {
// 验证如果用户不在房间内则不给发送
if (roomInfo[roomID].indexOf(user) === -1) {
return false;
}
socketIO.to(roomID).emit('msg',user,msg);
});

});

// room page
router.get('/room/:roomID',function (req,res) {
var roomID = req.params.roomID;

// 渲染页面数据(见views/room.hbs)
res.render('room',{
roomID: roomID,users: roomInfo[roomID]
});
});

app.use('/',router);

server.listen(3000,function () {
console.log('server listening on port 3000');
});

客户端代码

新增chatapp/views/room.hbs

{{roomID}} 昵称:
房间: {{roomID}}
当前在线人数:
在线用户:

<div id="msglog">