【已解决】socket.io 如何保存所有人的连接?现在是第2个人连接上,第1个人就收不到socket消息
发布于 2年前 作者 html5solo 3088 次浏览

更新了示例代码!

player = {};//注意:来自其他模块,并不是在本文件中定义的。用于保存所有用户的信息

io.sockets.on('connection', function (socket) {
    var currentUser = {//获取到的用户数据
        uid: 1000,
        socket: socket,
    };
    player[currentUser.uid] = currentUser;//保存用户连接

    currentUser.socket.on('login', function() {
        currentUser.socket.emit('login_result', 'yes');
    });
    currentUser.socket.on('test', function() {
        currentUser.socket.emit('test_result', 'something');
    });
});

在不使用session的情况下,可以用这种方式保存到所有用户的连接。 弊端嘛?人太多,player这个变量会很大很大。。

19 回复

看代码觉得没问题啊, socket 在函数闭包里边, 又没写成全局变量, 不会有覆盖呀

是必须用session么?我没有使用。

代码已更新

  • 应该是不会覆盖的啊
  • 当需要浏览器cookie来判断用户身份时,可用handshakeData得到sessionId,而且每个tab页面的socket是不一样的,所以即使userid唯一,也需要一个标识来指明到底消息来自于哪个tab,要发往哪个tab

@html5solo 楼上自己吧 socket 发送的对象实现了一遍?

请教哪里有handshakeData相关的代码示例?我在socket.io的github里都找到关于保持session相关的介绍。

@html5solo 1、没看懂问题 2、前端的代码没给出来

io.configure(function() {
        io.set('transports', [ 'websocket', 'htmlfile', 'xhr-polling', 'jsonp-polling' ]);
        io.set('authorization', function(handshakeData, callback) {
            // 没有cookie则退出
            if (!handshakeData.headers.cookie) {
                return callback('no found cookie.', false);
            }

           var signedCookies = require('express/node_modules/cookie').parse(handshakeData.headers.cookie);
            handshakeData.cookies = require('express/node_modules/connect/lib/utils').parseSignedCookies(signedCookies, app.get('config')['session_secret']);

            // 根据sessionId找username
            sessionStore.get(handshakeData.cookies['sid'], function(err, session) {
                if (err || !session)
                    return callback('no found session.', false);
                handshakeData.session = session;
                if (handshakeData.session.user) {
                    return callback(null, true);
                }
                else {
                    return callback('no found session.user', false);
                }
            });
        });
    });

@jiyinyiyong 我更新了帖子里的示例代码。您看看。

我现在在尝试第2种方式:我由于没有使用session,所以是将每个用户的socket保存在一个全局变量里。然后要给某个人发消息时,通过player[uid].socket.emit(。。。);

@html5solo 这样是挺奇怪的, 还是看 sumory 的代码吧

把player放到别的模块里面.然后提供add方法.这里调用的时候把socket传进去.socket就可以随时用了.

原来写过一个聊天室,我用的就是用数组保存登录进来的用户信息,之后再遍历数组发送消息出去,思路差不多是这样,好像socket.io有群发的API,很久木有关注这个了> <

@html5solo 每个socket都是独立的,绑定在它上面的事件也只能在你这个连接内触发,你要保存所有进来的socket连接,把它想像成dom事件绑定,想要每个dom事件都触发,那得一个一个emit,这方法比较笨哈^ ^

@gxmari007 有broadcast的api可以用

又仔细看了一下.你的 uid 重复了.

那个UID只是伪代码,呵呵。谢谢。

@gxmari007 @sumory @leizongmin @jiyinyiyong @kingdemonccgg 问题已经解决,就是按照我的第2种方法。感谢各位。

这个你多实验一下就知道了

回到顶部