Ajax轮询聊天在快速聊天中接收方前端会产生重复消息

4

我开发了一个使用以下技术的JavaScript聊天(后端使用PHP):

1) long-polling to get new messages for the receiver 
2) sessionStorage to store the counter of messages  
3) setInterval to read new messages and if sessionStorageCounter < setIntervalCounter then the last message is shown to receiver.
4) javascript to create,update and write the chat dialogues

这个模块工作良好,但是当用户进行快速聊天时,接收方的前端会收到两到三条相同的消息(计数器不失败,查询也不提供双重插入)。

代码似乎正确(这就是为什么我不提供代码的原因),所以时间间隔延迟可能是原因(缩短时间间隔延迟并没有改变任何内容)。

您认为上述架构是不好的做法吗?您认为哪种架构可以消除这些错误?


4
在添加新聊天消息之前,您可以随时检查 DOM,以查看是否已经存在相同的消息。这样,您就不会出现重复的消息。 - Robin
1
我给你的另一个建议是,如果你的应用程序需要实时聊天,为什么不考虑在服务器端使用socketio,并在后端使用node服务器来满足聊天应用程序的需求呢? - Robin
1
你在服务器端依赖于任何时间戳吗? - Muggles
感谢您提供 SocketIO 建议。目前我正在研究最佳的长轮询解决方案。 - Nik Drosakis
1
@Nikos 或许使用微秒时间戳可以产生更准确的结果。 - Muggles
显示剩余2条评论
2个回答

5

如果我要自己解决这个问题(而不是使用现有的库来处理),我的方法如下:

  • 服务器在每个消息到达时分配一个唯一的ID(GUID)。
  • 在客户端上,存储最近接收到的消息的ID。
  • 当轮询新消息时,使用最后成功接收到的消息的ID进行轮询。服务器然后通过在其自己的队列中查找该消息并重放所有随后的消息来响应。
  • 为了防止“丢失”的消息,每个消息还可以携带前一个消息的ID(允许客户端进行一致性检查)。

如果重新轮询导致服务器向客户端传递重复的消息,则每个消息上的唯一ID的存在使得消除它们变得微不足道。将服务器端消息队列视为事件流,每个客户端跟踪其最后读取的位置。客户端对消息的适当顺序、数量等不做猜测 - 因为其状态完全由“我看到了什么”组成,因此很少出现失步的机会。


0

由于这是实时聊天,setInterval 的间隔可能足够小,可以同时向服务器请求两到三次新消息。确保服务器处理程序同步,并忽略来自同一用户的重复查询。


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