首页 > 手游开发 > Unity3D > Unity使用BestHttp插件时Socket.IO保持长连接的问题
2019
11-26

Unity使用BestHttp插件时Socket.IO保持长连接的问题

Unity使用BestHttp插件时Socket.IO保持长连接的问题 - 第1张  | 逗分享开发经验

问题发现

最近在写一个对战小游戏的Demo,主要玩法是两个人互放地雷击败对手。小游戏的服务端是一个基于Socket.io的转发脚本,而客户端使用的是BestHttp插件提供的Socket.IO连接库。整个游戏的预览图如下所示:
Unity使用BestHttp插件时Socket.IO保持长连接的问题 - 第2张  | 逗分享开发经验

游戏运行后,客户端断线重连较为频繁,已经影响到游戏的正常运行。例如当发送地雷放置事件时,本方或对方正处于掉线状态导致该事件发送失败,客户端就无法正常响应。断线与重连的频繁程度可以参考下图:
Unity使用BestHttp插件时Socket.IO保持长连接的问题 - 第3张  | 逗分享开发经验

尝试解决

我查阅了一些资料,发现WebSocket协议是支持TCP长连接的,它定义了Ping、Pong两个事件来做心跳,以此进行长连接的维护。根据我的猜测,Socket.io理应封装了这些事件并自动维护长连接,那为什么上面连接的持续时间会这么短呢?

首先我猜测是协议问题,Socket.io会根据所处环境自动选取协议,它支持的协议如下:

  • WebSocket
  • Adobe Flash Socket
  • AJAX long polling
  • AJAX multipart streaming
  • Forever Iframe
  • JSONP Polling

于是我将链接都改成ws://开头,然而并没有什么卵用。之后,我尝试修改客户端的连接设置,例如断线重连、延迟重连等,也都没有效果。

最后,我把目光放在了服务端脚本上,既然WebSocket协议使用Ping、Pong进行心跳,那么有没有一种可能,即客户端心跳包发送间隔太长,服务器认为其超时而主动断开连接?于是我将代码进行了如下修改:
原来的服务端脚本

let server = require("http").createServer();
let io = require("socket.io")(server);

修改后的服务端脚本

let server = require("http").createServer();
let io = require("socket.io")(server,{'pingTimeout':6666666,'pingInterval':6666666});

修改完成后保存并重新运行脚本,之后开启两个游戏客户端进行对战,游戏存在的频繁断线重连问题得以解决。

猜想

由于我并不是太懂计算机网络,并且该插件也是闭源的收费插件,我只能猜测该插件在Socket.io的C#实现上有些小问题,也许是它发送心跳的间隔或处理方式与服务器API默认配置不符?不懂。

PS:在服务器脚本里设置一个超大的心跳间隔也只是缓兵之计,但对于随便写的小练习来说足够了。

最后编辑:
作者:游戏创作者大陆