把socket监听事件放在 app.js 文件中,emit() 和 on() 事件都能正常执行,但是如果把socket监听放到express的一个控制器里面,代码就会出现重复执行,重复的次数跟websocket连接个数相等,关键代码如下:
...app.js关键代码
var io = require('socket.io')(server);
io.on('connection', function(socket){
socket.emit('hi', 'hehehe');
socket.on('hehe', function(data){
console.log(data);
});
console.log(new Date()+' test');
})
这样的代码可以正常执行,但是如果将上面的代码放到express的控制器里面就会出现问题:
...app.js关键代码
var io = require('socket.io')(server);
app.use('/users', users.test(io));
...users.js关键代码
exports.test = function(io){
return function(req, res){
res.render('user', {'title': 'test'});
io.on('connection', function(socket){
socket.emit('hi', 'hehehe');
socket.on('hehe', function(data){
console.log(data);
});
console.log(new Date()+' test');
});
}
这样之后访问 localhost:3000/users 服务器下的输出内容跟websocket连接数相关,比如打开一个页面,console.log(data)
这行会输出一次,刷新一次页面,则这行会输出两次,新建一个标签页打开这个页面的效果跟刷新一样,就好像在控制器下的socket监听的是所有的连接,为什么会出现这种情况?
如果socket要跟session交互,这个时候该怎么处理?
@leapon 嗯嗯谢谢 我刚接触node还有点不理解,每次刷新socket连接不是会断掉重连吗,为什么在 /users 下面刷新一次会增加一个socket连接?是跟 app.use('/users', users.test(io));
这句话有关吗?它hold住这个socket连接了吗?
@hoozi 嗯嗯谢谢 初入node还有很多不明白的地方,如果将socket作为一个独立的服务运行,这个socket服务器要监听创建的http服务器还是单独一个端口?对socket连接进行验证的时候是通过解密cookie吗
@tashuo 可以,只是你的理解方式不对,http server 和 socket server 是分开的两层。
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket){
console.log("url"+socket.handshake.url);
clientId=socket.handshake.query.clientId;
console.log("connected clientId:"+clientId);
});
server.listen(3000);
上面的意思将 socket.io 附加到 http server 上,当 http server 接收到 upgrade websocket 时就将请求转给 socket.io 处理。如果你要根据 url 进行动作,在 on connection 进行处理。
@klesh 嗯谢谢 我现在在connection事件里面处理各个socket事件请求,只在socket连接建立前进行登录验证 authorization,并没有用到 socket.handshake.url ,这样做会有逻辑问题或安全问题吗,因为不同的socket事件存在于不同的url中?
@tashuo 你的意思是要有 authorization 的请求才允许连接吗? 虽然我没实操经验,但是 express 是使用 connect 作为中间件管理的。 当有新的 http request 进来,connect 依次执行中间件,中间件们可以对信息进行加工,或者中断执行之类。。。 authorization 和 socket.io 应该都是以中间件形式插入到 connect 里面。 那么只要 authorization 发生在 socket.io 之前就能对未授权的 request 进行截停。 也就是说这两个中间件各自处理自己感兴趣的事情,你只要整理好前后顺序就行了。