标题更新:[用Node实现WebSocket协议] - 原:[WebSocket在高并发和大数据情况下的传输问题]
发布于 10 年前 作者 abbshr 20090 次浏览 最后一次编辑是 8 年前

下面是之前遇到的问题:

上周在班里做了关于WebSocket协议的技术分享,因为当时演示的是小数据、间歇性数据发送。所以很成功,并没有遇到啥问题。

不过回去之后发现用一个10000次的循环不断向服务器发送数据时,不论数据的大小,后几千次的数据都变成了乱码:

for (i = 0; i < 10000; i++) ws.send('a');

另外一个问题是,当我发送了一次长度为65535 byte的数据(也就是Payload_len = 126, Payload length = Math.pow(2, 16) - 1),服务器却得到了两次的数据请求:

第一次是FIN = 1, Opcode = 0, Payload length为65535的Frame;
第二次是FIN = 1, Opcode为随机, MASK也是随机的, Payload length还是随机。。。

可是经过查看发现第一次数据的实际长度往往是Payload length值的一半左右,第二次的数据全是乱码。

下面是WebSocket握手结束后数据解码部分的代码:

function decodeFrame(frame) {
    var counter = 0;

    var fin_offset = 7,
        opcode_offset = parseInt(1111, 2),
        mask_offset = 7,
        payload_len_offset = parseInt(1111111, 2);

    var FIN = frame[counter] >> fin_offset,
        Opcode = frame[counter++] & opcode_offset,
        MASK = frame[counter] >> mask_offset,
        Payload_len = frame[counter++] & payload_len_offset;

    Payload_len === 126 && 
    (Payload_len = frame.readUInt16BE(counter)) && 
    counter += 2;
    
    Payload_len === 127 && 
    (Payload_len = frame.readUInt32BE(counter + 4)) && 
    counter += 8;

    var Payload_data = [];

    if (MASK) {
        var Masking_key = frame.slice(counter, counter + 4);

        counter += 4;

        for (var i = 0; i < Payload_len; i++) {
            var j = i % 4;
            frame[counter + i] ^= Masking_key[j];
        }
    }
    
    // 这里得到上面说的测试结果
    return {
        FIN: FIN,
        Opcode: Opcode,
        MASK: MASK,
        Payload_len: Payload_len,
        Payload_data: frame.slice(counter, Payload_len)
    }

};

WebSocket协议还有什么细节需要处理还是Buffer无法瞬间接受过大的数据吗?

一直没想明白这两种情况下乱码究竟是怎么产生的。。

求社区神牛指导啊~~


问题终于解决~

实现WebSocket真够让人纠结的,正确的代码已上传至github : https://github.com/abbshr/websocket_talk

在这方面遇到麻烦的同学可以参考参考啦~

5 回复

WebSocket协议本身定义是没有问题的,应该是你的发送端处理或接收端的处理有问题。

恩,已解决,不过这个问题产生的原因确实很蛋疼。。 的确是读取的问题。要在读取时循环调用解码函数。

@myy 的确有现成的,后来也读了部分源码,不过还是想自己写个玩玩

回到顶部