websocket数据包大小的问题

目前在做一个项目的前期测试,打算采用websocket通讯。在web平台表现尚可。但在模拟器上出现了问题。

如果数据包较大>1024发现会出现拼包错乱的问题(会把两个包的数据和并到一个回调里面通知,导致我游戏层解析数据的时候发生错误,目前数据采用明文json格式发送)。

因为不太了解websocket,根据网上的普遍做法我在onmessage里面没有做拼包,认为凡是onmessage回调应该就是一个完整的数据包了。这个貌似在web平台上是这个样子。但是到了模拟器上就出现>1024会和后面的数据合并回调。
日志如下:

Simulator : NOTICE: instantiating client ext permessage-deflate
Simulator : Safely done, msg(1)!
Simulator : msg(1) append: 0 + 228 = 228
Simulator : msg(1) was totally sent!
Simulator : -----------------------------------------------------------
Simulator : Receiving data:index:1, len=30
Simulator : Notify data len 30 to Cocos thread.
Simulator : Safely done, msg(2)!
Simulator : msg(2) append: 0 + 1284 = 1284
Simulator : msg(2) was totally sent!
Simulator : -----------------------------------------------------------
Simulator : Receiving data:index:2, len=1023
Simulator : Receiving data:index:3, len=689
Simulator : Receiving data:index:4, len=1023
Simulator : ERR: lws_rx_sm: doing draining flow
Simulator :
Simulator : Receiving data:index:5, len=1023
Simulator : Receiving data:index:6, len=1023
Simulator : Receiving data:index:7, len=1023
Simulator : Receiving data:index:8, len=216
Simulator : Notify data len 1712 to Cocos thread.
Simulator : Notify data len 4308 to Cocos thread.
Simulator : 20846:SyntaxError: JSON.parse: bad Unicode escape at line 1 column 1018 of the JSON data
_ at a (F:\GitHub\TTGamePlaza\library\bundle.project.js?009:NaN:0)_

1赞

多谢反馈,这个问题我们已经在处理当中

@marvin436

临时解决方案,可以把permessage-deflate的extension关闭
方法为:
https://github.com/cocos2d/cocos2d-x/blob/v3/cocos/network/WebSocket.cpp line598
// info.extensions = exts; // 注释掉这行赋值语句

我尝试用我的demo来重现这个问题,但是无法重现。请问你那里是用哪种websocket服务端?
能否提供重现此问题的服务端代码片段?谢谢。

@marvin436, 从你提供的日志中看,的确是发送了两次数据给服务器,服务器响应了两次。

  • 是windows版本的模拟器还是mac版本的?
  • 真机运行是否也会出现此情况?

我现在只能在模拟器上面运行 真机上面有个js错误没解决 这个错误在模拟器上也有 但是模拟器是可以正常运行的
日志如下:
Simulator : 7387:mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create

另外我这边服务器是用nodejs写的 用的Buffer加密成base64编码的字符串传输的

两个问题:

  1. 请问是使用https://github.com/sitegui/nodejs-websocket 这个库么?
  2. 服务端是否有手动开启permessage-deflate?

我用的ws这个第三方库

能否具体告知这个扩展库的主页或者github地址?或者具体的名称?
或者如何通过npm安装的?

https://github.com/websockets/ws

谢谢,我这里再尝试用这个库重现一下这个问题。

@marvin436, 我这里还是无法重现你说的问题。能否整理一个跟你项目无关的小demo,重现出此问题。
非常感谢。

我之前的项目,真机web和apk都没问题,pc的web也没问题。只有 模拟器时,有问题websocket 接受服务器的消息时 有几率崩溃。(直接使用的websocket,没有用第三方)

请问,是在windows下的模拟器还是mac下的?

var WebSocketServer = require(‘ws’).Server;

//webserver
var server = new WebSocketServer({ port: 3000 });

//连接事件
server.on(‘connection’, function (socket) {

//辅助函数
function SendToClient(wMainCmdID, wSubCmdID, Data) {
    try {
        //计算数据包大小
        var wPacketSize = 6;
        if (arguments.length === 3 && Data !== undefined) {
            wPacketSize = wPacketSize + Data.length;
        }

        //构造数据包
        var buf = new Buffer(wPacketSize);
        buf.fill(0);

        //命令填充
        buf.writeUInt16LE(wPacketSize, 0);
        buf.writeUInt16LE(wMainCmdID, 2);
        buf.writeUInt16LE(wSubCmdID, 4);

        //附加数据
        if (arguments.length === 3 && Data !== undefined) {
            buf.fill(Data, 6);
        }

        //发送数据            
        socket.send(JSON.stringify(buf));
    }
    catch (e) {
        console.log(e);
    }
}

//测试
SendToClient(1, 100, new Buffer(4195).fill(1));
SendToClient(1, 101, new Buffer(8195).fill(16));
SendToClient(2, 100, new Buffer(129).fill(2));

//转发客户端消息
socket.on('message', function (data) {
    
});

//与客户端连接断开
socket.on('close', function () {
    
});

});

server.on(“error”, function () {
console.log(‘server error.’);
})

终于在iphone6上重现了这个问题,mac上是没问题的。
我会继续跟进这个问题。谢谢反馈。

已经反馈给libwebsockets官方https://github.com/warmcat/libwebsockets/issues/593

你好,我也遇到了该问题,在github上有at你。。
确定是libwebsocket的问题了吗?那就只有坐等了。。

我的server是pomelo,之前用cocos2d-x v3.10版本的websocket跑了几个月没出现过问题。
就是在换了最新patch里的websocket导致。我想确认下,如果我换回v3.10的websocket,能支持IPv6吗?

不用坐等啊,先可以通过注释掉extension,禁用压缩功能。
改动方法是:查找WebSocket.cpp中的info.extensions = exts;
将这行注释掉即可。

@dumganhar,谢谢回复。已经这么干了,苹果加急一天过了。
但是感觉初次加载会比之前效率慢一点点。