WebSocket Draft 10向客户端写文本数据的实现

在Draft 10中,如果解析数据的过程弄清楚了,这个就更简单了,返回数据的格式和之前接受到的数据格式非常类似,只是你不用生成mask了,头部的其他格式还是一模一样的。

第一个字节还是固定的,是0x81,意义和接受数据的意义一样,第二个字节也是,后七个位表示数据长度,由于没有mask,所以第一位是0;长度的表示方法和接受的标识方法一致,可能用7位表示,也可能用16位表示。

用NodeJS实现如下:

var socketWriter = {
    'draft10': function(socket, data){
        var frames,
            length = new Buffer(data, 'utf8').length;
        if(data.length 0x7d){
            frames = new Buffer(4);
            frames[0] = 0x81;
            frames[1] = 0x7e;
            frames[2] = length 8;
            frames[3] = length & 0xFF;

WebSocket草案10文本数据解析实现

握手协议实现了,接下来就是解析数据了,这个相对来说要麻烦很多,相比草案7.6变得更复杂了。下图是数据传输的格式:

各个值的具体含义可以参考这个中文翻译:http://blog.csdn.net/fenglibing/article/details/6852497,英文原文在这里:http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#section-4.2

简单概括一下就是:FIN一直为1,RSV1、RSV2、RSV3一直为0,当发送内容为文本时,opcode为1,MASK如果为1就使用掩码,需要获取四位掩码,依次轮流和数据做异或运算,第一个内容数据与第一个掩码异或,第二个内容数据与第二个掩码异或……第五个内容数据与第一个掩码异或……一直到结束,然后再对内容进行编码就可以了。

在Chrome/Firefox下面,FIN永远为1,如果只是文本消息,opcode一直是1,RSV1、RSV2、RSV3都为0,所以第一个数据是0x81;MASK为1,再跟上数据长度,所以第二个数据会大于0x80,由于数据长度不一样,其需要占用的字节数也不一样,因此掩码的位置也不一样。根据规范,换算下来是这样:数据总长度(包含FIN、RSV等等信息)小于0x84,则掩码为第三个数据到第六个数据;数据总长度(包含FIN、RSV等等信息)小于0xfe81,则掩码为第五个数据到第八个数据;其他掩码则为第十三个数据到第十六个数据。当数据长度超过一个包的长度时,后面的数据包不再包含RIN、RSV和MASK等信息,二是直接为内容数据,需要根据上一次取到的MASK来做异或运算。…

WebSocket草案10握手协议的实现

Chrome早就采用了websocket草案10的协议,很多以前支持websocket的代码突然之间都用不了了,很多作者也没空更新,索性自己看了下草案,自己实现了一套。

握手协议还是非常简单的,Chrome发过来的header大概是这样的:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 8

要答复的头大概是这样的:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: