npm install --save express
npm install --save socket.io
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.send('Welcome Realtime Server
');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
var onlineUsers = new Array();
var users = {};
io.sockets.on('connection', function (socket) {
io.sockets.emit('connect',{'status':'正确'});
console.log("new conns join ..");
socket.on('private message', function (from,to,msg) {
console.log('I received a private message by ', from, ' say to ',to, msg);
if(to in users){
users[to].emit('to'+to,{mess:msg});
}
});
socket.on('new user',function(data){
//console.log("socket标示为:"+socket.id);
if(data in users){
}else{
var nickname = data;
users[nickname]= socket;
onlineUsers.push(data);
console.log('用户'+data+'加入聊天室');
console.log('当前的在线用户有 '+onlineUsers);
}
io.sockets.emit('online users',onlineUsers);
});
socket.on('disconnect', function () {
var logoutUserName ;
for(var obj in users){
console.log("obj的值是:"+obj);
if(users[obj] == socket){
console.log(obj+"用户退出聊天室");
logoutUserName = obj;
delete users[obj];
}
}
for(var i = 0; i
多人聊天室
姓名:
//js 对象
var a = {};
//特殊的方法对对象进行复制
a['a'] = "aaa";
a['b'] = "bbb";
a['c'] = "ccc";
console.log(a);
//结果
//{a:'aaa',b:'bbb',c:'ccc'}
for(var obj in a){
//遍历对象中所有的属性
if(a[obj] == "bbb"){
console.log(a[obj]);
//删除该属性
delete a[obj];
}
if(obj == 'function'){
console.log('这是一个方法');
}
console.log(obj);
}
// send to current request socket client
socket.emit('message', "this is a test");
// sending to all clients except sender
socket.broadcast.emit('message', "this is a test");
// sending to all clients in 'game' room(channel) except sender
socket.broadcast.to('game').emit('message', 'nice game');
// sending to all clients, include sender
io.sockets.emit('message', "this is a test");
// sending to all clients in 'game' room(channel), include sender
io.sockets.in('game').emit('message', 'cool game');
// sending to individual socketid
io.sockets.socket(socketid).emit('message', 'for your eyes only');
请注意,由于版本问题如果上述的io.sockets.scoket(socketid).emit(),该方法不能正常使用,请这样写,io.sockets.connected[socketid].emit('message',msg);
上述集中方式为socket.io常用的数据传输方式
io.sockets.on('connection', function (socket) {
});
回调函数的socket参数为一个 client
与服务器的连接标示,不同的 client
会有不同的连接标示。
socket.emit socket.emit
信息传输对象为当前 socket
对应的 client
,各个 client socket
相互不影响。
socket.broadcast.emit socket.broadcast.emit
信息传输对象为所有 client
,排除当前 socket
对应的 client
。
io.sockets.emit
信息传输对象为所有 client
。
类似于之前提过的 of
方法生成命名空间来管理用户, socket.io
可以使用分组方法, socket.join()
,以及与之对应的 socket.leave()
。
io.sockets.on('connection', function (socket) {
socket.on('firefox', function (data) {
socket.join('firefox');
});
socket.on('chrome',function(data){
socket.join('chrome');
});
});
假设有两个聊天室,一个名为firefox,另一个为chrome,客户端操作
socket.emit('firefox')
,就可以加入 firefox
聊天室; socket.emit('chrome')
,就可以加入 chrome
聊天室;
向一个分组传输消息,有两种方式:
socket.broadcast.to('chrome').emit('event_name', data);
//emit to 'room' except this socket client
io.sockets.in('chrome').emit('event_name', data)
//emit to all socket client in the room
broadcast
方法允许当前 socket client
不在该分组内。
可能有一个疑问,一个 socket
是否可以同时存在于几个分组,等效于一个用户会同时在几个聊天室活跃,答案是”可以“, socket.join()
添加进去就可以了。官方提供了订阅模式的示例:
socket.on('subscribe', function(data) {
socket.join(data.room);
})
socket.on('unsubscribe', function(data) {
socket.leave(data.room);
})
后台处理订阅/退订事件
socket = io.connect('http://127.0.0.1:1338/');
socket.emit('subscribe',{"room" : "chrome"};
socket.emit('unsubscribe',{"room" : "chrome"};
前端触发订阅/退订事件,就可以加入对应的聊天室。 通过 of
方法也可以通过划分命名空间的方式,实现聊天室功能,但不如分组管理来的方便。
socket
连接需要添加权限验证,让已登录的用户 socket
连接到服务器,未登录的用户无条件拒绝。全局授权管理如下:io.sockets.authorization(function (handshakeData, callback) {
callback(null, true);
}).
callback
函数有两个参数,第一个为 error
,第二个参数为是否授权bool值,通过授权回调函数应为 callback(null,true)
,其它情况下都为拒绝建立连接。
按照web的开发方式,检测是否登录首选 cookie-session
来实现,问题也是出在这里。 websocket
握手阶段属于 HTTP
协议,简单来说是可以读到cookie,就可以实现session。
+ 精准单用户推送
理论上来说
// sending to individual socketid
io.sockets.socket(socketid).emit('message', 'for your eyes only');
就可以向一个特定用户推送消息,但是如何获得这个 socketId
,就是生成一个哈希数组,key为username,值为socket.id,这样就可以通过用户名获取对应的id,进而可以向特定client推送消息。
如果是想关机的时候让服务不间断,后台运行,nohup node index.js(文件名) &如果是想简单启动,写个启动脚本,将nohup node index.js(文件名) 写入.sh文件