解决 Socket.io 事件被重复触发的问题

问题描述

在使用 Socket.io 进行实时通信过程中,可能会出现事件被重复触发的情况,也就是说一个事件在被触发后,会再次触发多次,给应用带来不必要的负担和错误。

原因分析

Socket.io 模块在实现内部事件分发机制时,会对每个事件做一次遍历,然后按照优先级、事件名等规则将事件分为不同的组,最后进行分发。但这个过程有时会出现问题,比如网络延迟、事件触发频率过高等原因导致事件被重复触发。

解决方法

  1. 事件去重:在客户端添加一个事件队列,每次接收到事件时,将事件的名称和数据存到队列中,然后在队列的开头和结尾分别加上一个标志,每次触发事件时,判断标志是否存在,只有标志不存在时才处理该事件并将标志添加到队列中。
-- ---
----- ----------- - --
------------------ ------ -- -
  ----- ----- - - ----- -------- ---- -
  ----- --------- - - ----- -------- ----- -- -
  ----- ------- - - ----- ------ ----- -- -
  --------------------------
  ------------------------------
  -------------------------
  -- -------------------- --- -------- ------
  -------------------
  ----- ------------------- - - -- ------------------- --- ------ -
    ----- ----- - -------------------
    -- ------
  -
  -------------------
--
  1. 事件间隔限制:在客户端设置一个事件触发的最小间隔时间,当收到事件时,判断该事件距离上一次触发的时间是否超过最小间隔时间,如果没有超过,则不处理该事件。
-- ---
--- ------------- - -
----- ----------- - ---- -- ------- - -
------------------ ------ -- -
  ----- - - ----------
  -- -- - ------------- - ------------ ------
  ------------- - -
  -- ------
--
  1. 事件确认机制:在服务端实现一个事件确认机制,在客户端发送事件时,在事件名称后添加一个唯一标识符,服务端接收到事件后,将该标识符存到一个已接收标识符的集合中,然后将确认信息返回给客户端,客户端收到确认信息后,将该事件标识符从已发送标识符的集合中删除,当客户端再次发送事件时,判断该标识符是否在已发送标识符的集合中,如果在,则不发送该事件。
-- ---
----- -------- - --- -----
-------------------- ---- -- -
  -------------------
--
------------------ ------ -- -
  ----- -- - ---------------------
  -- ------------------ ------
  ----------------
  -------------------- - --- ---- --
--

-- ---
----- ---------- - --- -----
------------------ -- --- ---- -- -- -
  -- -------------------- ------
  ------------------
  -- ------
  ---------------------- ---
--

结论

解决 Socket.io 事件被重复触发的问题可以通过以下几种方法实现:事件去重、事件间隔限制、事件确认机制。采用何种方法取决于具体情况,需要根据实际情况进行选择。

参考文献

《深入浅出Node.js》

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/671e2f0a2e7021665ef68bea