把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交互,这个时候该怎么处理?
connection event 就像是敲门,你整一个人去开门就好了。 第二段代码是每访问一次/users,你就派个人去门口,这样一开门,好几个人去问候,没必要嘛。
和session的交互,就交给在门口的那一个人处理好了
我一般把socket服务独立运行,看你的代码 不觉得怪怪的吗 自豪地采用 CNodeJS ionic
楼主是想把它挂载到某个url上吧。这样做是错的。
@leapon 嗯嗯谢谢 我刚接触node还有点不理解,每次刷新socket连接不是会断掉重连吗,为什么在 /users 下面刷新一次会增加一个socket连接?是跟 app.use('/users', users.test(io));
这句话有关吗?它hold住这个socket连接了吗?
@hoozi 嗯嗯谢谢 初入node还有很多不明白的地方,如果将socket作为一个独立的服务运行,这个socket服务器要监听创建的http服务器还是单独一个端口?对socket连接进行验证的时候是通过解密cookie吗
@klesh 哦,也就是socket不能跟express的控制器相匹配工作?
@tashuo 监听同一个server,socketid和sessionid 貌似不是同一个东西
@hoozi 我也是在学习当中,如果要绑定登录用户的话,我用了一个变量user={}来存储每一个socket,跟数据库中的用户对应起来,但是这种做法不是持久化的。
@hoozi 嗯谢谢 我试一下这种方法
eaferaf
@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中?
你这样的话,每次刷新都会绑定一个新的监听对象
@klesh 嗯嗯了解了,谢谢
@jerrywu55 嗯谢谢