2016-11-08 318 views
0

我一直在阅读有关此问题的答案,现在已经有一段时间了,但没有一个解决方案似乎适用于我的设置。Socket.io页面刷新与房间断开连接

我有一个nodeJS服务器连同express。我使用Socket.io向个人用户发送通知。 (前端是Angular)

当用户登录时,他加入以他的电子邮件地址(唯一)命名的房间。

io.on('connection', function (socket) { 
    socket.on('join', function(user) { 
     //list of connected users 
     connected_users.push({socket_id: socket.id, email: user.email}); 
     socket.join(user.email); 
    }); 
    ... 

join事件从角广播时在用户登录

这样我可以通过使用电子邮件地址发送邮件,像这样简单地通知:

io.sockets.in(to).emit('notification', { 
    message: msg, 
    source: from, 
    destination: to, 
    event: data 
}); 

当用户手动注销我注册了以下事件监听器:

socket.on('leave', function(user) { 
    //remove the user from the list 
    var index = findUserConnected(socket.id); 
    if(index != null) { 
    connected_users.splice(index, 1); 
    } 
    socket.leave(user.email); 
}); 

socket.on('disconnect', function() { 
    //if the user refreshes the page, he is still in the connected users list 
    var email = findEmailUserConnected(socket.id); 
    if(email != null) { 
    //we make him join back his room 
    socket.join(email); 
    } 
}); 

技术上这个作品:终于有每当用户注销或刷新页面是在disconnect处理程序。在页面刷新时,用户加入他的房间。

问题只出现在页面刷新上,即使用户在他的房间里也没有收到使用io.sockets.in(email).emit('notification', {});发送的通知。

显然页面刷新调用socket.disconnect(),它会生成一个新的socket_id。我不确定是否有办法将socket_id重新分配给一个房间或类似的东西。

+0

页面重新加载会破坏所有页面资源,包括webSocket/socket.io连接。再次加载页面会创建一个新的连接。您可能需要使用cookie来创建某种持久的会话ID,以便您可以识别以前的用户并在服务器上恢复其状态。 – jfriend00

+0

@ jfriend00“恢复其在服务器上的状态”是什么意思?当页面刷新时,我已经有了socket.join,用户被识别出来......等等。 – gyc

+0

在发生'connection'事件时,您需要能够识别您之前配置到一个房间中的套接字并将其状态恢复为您想要的方式(将它放回房间中,更新'socket.id'属于这个用户,等等......通常,人们会使用从cookie中获得的信息将这个新的传入连接与您以前见过的特定用户关联起来 – jfriend00

回答

1

确定首先在服务器上收到'disconnect'事件意味着该套接字上的连接将要终止。所以,你现在正在做一个同样的套接字连接回房间是没有用的。

socket.on('disconnect', function() { 
    var email = findEmailUserConnected(socket.id); 
    if(email != null) { 
     socket.join(email); // this would never work because this socket connection is not going to exist anymore. 
    } 
}); 

我的建议是确保每次建立新连接时用户总是重新回到房间(电子邮件)。通过在每个新连接上添加发送连接事件可以轻松完成。 在您的客户端代码做

var socket = io(); 
socket.on('connect', function() { // 'connect' event is received on client on every connection start. 
    socket.emit('join', user); // where 'user' is your object containing email. 
}) 

这样,它确保每当建立一个新的连接联合事件被发送到服务器和“socket.on(”加入,...)”监听器你的服务器将把新的套接字添加到房间中。希望这有助于:)

相关问题