一般在客户端非浏览器环境/node.js等会遇到这样的情况,需要socket.io v2客户端(常见于Unity中的BestHTTP)连v3/v4服务器。但是由于v3的断代性变化,导致连不上。
先说结论:v2版客户端连接v3/v4服务器不需要客户端做什么,仅需服务端开启allowEIO3: true选项。但用BestHTTP的情况又不一样。
BestHTTP连socket.io服务器
BestHTTP v1中的socket.io v2客户端连v3/v4服务器一般会出现如下错误(Unity Editor中):
Ex [PollingTransport]: ParseResponse - Message: 1: Index and count must refer to a location within the buffer.
Parameter name: bytes at System.Text.UTF8Encoding.GetString (System.Byte[] bytes, System.Int32 index, System.Int32 count) [0x00057] in <695d1cc93cca45069c528c15c9fdd749>:0
at BestHTTP.SocketIO.Transports.PollingTransport.ParseResponse (BestHTTP.HTTPResponse resp) [0x000e5]
解决方案:
(1)客户端采用BestHTTP v1,用其中的socket.io v2:服务端只能用socket.io v2。但由于socket.io直到v3开始才给出TypeScript的类型声明,故服务端要使用TypeScript,只能把socket.io v2的变量声明成any类型。自己搞v2的.d.ts,工作量太大,如果你搞出来了,经测试没有问题,可以考虑共享到npm @type。
(2)客户端升级BestHTTP v1到v2,但是仍然用其中的socket.io v2。服务端可以用socket.io v2/v3/v4,v3/v4要开启allowEIO3: true。
(3)客户端直接用BestHTTP v2中的socket.io v3/v4,一切OK。
我不确定是否所有BestHTTP v1都无法正常连接开启allowEIO3: true选项的socket.io v3/v4服务器,但是至少到BestHTTP v1.10.x都不能连上,尽管它们号称支持socket.io v2。
v3/v4服务器开启allowEIO3: true选项
非常简单,在require socket.io的时候按如下方法开启:
var io = require('socket.io')(http, {
allowEIO3: true // false by default
});
参考
Migrating from 2.x to 3.0 | Socket.IO
https://benedicht.github.io/BestHTTP-Documentation/pages/best_http2/protocols/socketio/socketio.html