如何处理Socket.io客户端聊天应用中的页面重新加载

5

我正在实现一个聊天应用程序。我不在服务器上,包含JavaScript文件的页面可以是文件系统上的任何HTML页面,其中嵌入了JavaScript和Socket.io。

现在的问题是,根据定义,页面重新加载将始终触发新请求,导致新的Socket连接。

$(document).ready(function() {

var messages = [];
socket = io.connect(connectionString);
///next code sequence
});

我想实现的是即使在页面重新加载后,我的会话仍然可以保持。 现在经典的实现方式是: 1)我可以保持一个经典的实现。一旦完成,我可以保留先前的sessionid,并从数据库中重新获取以前的会话/聊天并继续。 但上述方法非常笨拙和耗时。 有更好的方法吗?
2个回答

7

每次页面刷新或用户导航,webSockets都会断开并重新连接。正如你所知道的那样,这就是它们的工作方式。

如果您想为用户创建一个持久会话,则可以简单地执行任何网页用于使用cookie识别会话或用户的操作。如果您的站点具有用户登录功能,则当用户连接时,您可以从其登录cookie中获取该用户的标识,并将其用作任何webSocket连接的持续性用户标识符。由于任何webSocket连接始于http请求,因此该cookie将始终存在。

如果/当用户重新加载或导航到站点上的另一页时,webSocket将断开连接,重新连接时,用户登录cookie将再次存在。


如果您还没有用户登录cookie,则可以在用户首次连接时检测到没有用户标识cookie,并设置此类cookie,以便未来重新连接时存在。然后,此cookie中的标识符将成为您的数据库中的一个键,以便您将浏览器与给定用户的数据相关联。

如果您的服务器需要知道用户何时实际离开,则可以实现某种形式的服务器端超时。当用户保持断开连接一段时间(例如几分钟)时,就清楚了该用户不仅仅是短暂地在页面之间导航,您可以将其标记为已注销。但是,在正常的重新加载或页面导航期间,用户将始终在几秒钟内重新连接,因此您的服务器不会注销它们。


如果您有仅在客户端可用的数据,则还可以将其存储在浏览器中的本地存储中,以提高从页面到页面的效率(因此可以将数据存储在本地,然后读取它,而无需从服务器获取它),但这使得数据仅在特定计算机上的特定浏览器中可用,这通常不是您想要的,如果数据与用户登录相关,并且您希望该数据对该用户在哪个浏览器或计算机上登录都可用。


服务器断开时间增加的唯一问题是,在重新加载时套接字会发生更改。 - ManMohan Vyas
@ManMohanVyas - 是的,重新加载会导致新的套接字连接。这是无法避免的。 - jfriend00
我正在基于socket维护会话,因为在断开连接时我只能得到socket。我需要回答的最后一件事是,如果我频繁使用setInterval()函数,它是否会使用更多资源,我的聊天应用程序将有大约10k并发用户? - ManMohan Vyas
@ManMohanVyas - 这取决于您调用 setInterval() 的频率以及每次调用时要执行的操作。如果使用不当,它可能会占用大量服务器资源。偶尔使用则几乎不会被注意到。您应该通过其他方式识别用户(例如,在连接时可以看到的 cookie),然后将该标识符作为自定义属性放在 socket 对象上。 - jfriend00
这是我采取的确切方法。在我的情况下,我将读取cookie的逻辑放置在连接侦听器中,当新客户端连接到套接字时会调用该侦听器。然后,如果存在cookie,我只需从数据库中加载以前的状态,这仅在连接的生命周期内执行一次。如果客户端再次断开连接,则再次执行相同操作。 至于如何知道客户端何时刷新,我的想法是在cookie中设置一个计数器变量,每次页面刷新时都会增加。服务器读取此cookie并知道客户端是否已刷新。 - Dave Kalu

0

2
我没有使用AngularJS。 - ManMohan Vyas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接