文章发布于:2024年2月12日

下午玩在线五子棋,玩到中途,快到决定胜负的时候,轮到对手落子时,结果迟迟不见动静。我以为对方在思考,一直等着,过了一会,觉得这也太久了吧?随手打开浏览器调试窗口,操!我掉线了。

不知道对方等了多久,总之感觉有点愧疚,于是决定增加两个功能:第一提醒自己掉线,第二提醒自己对方掉线。

提醒自己掉线很简单,因为本来浏览器和服务器之间就有“ping-pong”(简称PP)通信,现在只需要在超时的时候,让浏览器弹出一个提醒就可以了。

提醒自己对方掉线要怎么做呢?

开始的时候想,或许每次 PP 通信,都创建一个 setTimeout 的定时,如果超出这个定时没有触发下一次PP 通信,就告诉另一方,对方掉线了。

但是又想,这等于每次都要创建两个(两个用户) setTimeout 任务,是不是太繁琐了?有没有其它的办法?

后来的解决办法是,利用相互之间的 PP 通信来检查。

当一方 PP 通信时,获取时间,更新自己的时间,然后检查当前时间与对手上一次的 PP 通信时间间隔是否大于20s + s(双方 PP 通信不同步,会存在最大 20s 的正常差值,加上n,让其满足判断)。如果大于,说明对手已经长时间没有完成 PP 通信,可以提醒自己,对手掉线了。

这个看起来也挺繁琐,不过我觉得,这些操作不过是在桌子对象上增加三个属性,然后再做一些简单的计算,比起每次都创建两个 setTimeout 任务强。可以想象,如果有许多桌子(不太可能),每个桌子都每间隔20秒创建两个 setTimeout 任务,对服务器或许有些压力(不太确定)。