CNode

【已解决】socket.io 如何保存所有人的连接?现在是第2个人连接上,第1个人就收不到socket消息

Hhtml5solo发布于14 年前最后回复14 年前19 回复12329 浏览0 收藏

更新了示例代码!

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)

L
leizongmin#1·14 年前

@gxmari007 求指导啊

J
jiyinyiyong#2·14 年前

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

H
html5solo#4·14 年前
S
sumory#5·14 年前
  • 应该是不会覆盖的啊
  • 当需要浏览器cookie来判断用户身份时,可用handshakeData得到sessionId,而且每个tab页面的socket是不一样的,所以即使userid唯一,也需要一个标识来指明到底消息来自于哪个tab,要发往哪个tab
J
jiyinyiyong#6·14 年前
H
html5solo#7·14 年前
L
leizongmin#8·14 年前
引用 leizongmin@gxmari007 求指导啊

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

S
sumory#9·14 年前
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);
                }
            });
        });
    });
H
html5solo#10·14 年前
引用 jiyinyiyong看代码觉得没问题啊, socket 在函数闭包里边, 又没写成全局变量, 不会有覆盖呀

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

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

J
jiyinyiyong#11·14 年前
K
kingdemonccgg#12·14 年前

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

G
gxmari007#13·14 年前
引用 leizongmin@gxmari007 求指导啊

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

G
gxmari007#14·14 年前
引用 leizongmin@gxmari007 求指导啊

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

S
sumory#15·14 年前
引用 leizongmin@gxmari007 求指导啊

@gxmari007 有broadcast的api可以用

K
kingdemonccgg#16·14 年前

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

H
html5solo#17·14 年前
引用 kingdemonccgg又仔细看了一下.你的 uid 重复了.

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

H
html5solo#18·14 年前

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

参与回复
登录后即可参与回复。登录