美文网首页
(二)gof websocket消息处理

(二)gof websocket消息处理

作者: 公式般欢笑 | 来源:发表于2021-03-06 21:36 被阅读0次

    本项目地址:gof 一个支持百万连接的websocket框架
    本文提及的内容包含在:conn.go
    上一章节中,我们创建了一个epoll结构体,并在该结构体中记录了一个epoll对象。接下来我们就需要通过初始化该对象,从而实现消息的接收。

    一、WebSocket的流程

    首先,websocket也是作用在tcp连接之上的。因此,websocket的工作过程如下:

    1、三次握手

    这个过程是在Tcp层完成的。而我们的gof是应用层,所以这份工作,linux底层 已经帮我们完成了。

    2、发送header头

    握手完成之后,会在服务端建立一个socket句柄,首先接收到的消息就是客户端发送的header头信息。其中包含一下几个内容:

    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    Cache-Control: no-cache
    Connection: Upgrade
    Host: 127.0.0.1:8801
    Origin: http://www.easyswoole.com
    Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
    Sec-WebSocket-Key: qHHCi/x3CScAZASynxuiJA==
    Sec-WebSocket-Version: 13
    Upgrade: websocket

    3、服务端回应消息头

    服务端在收到消息头之后需要对客户端进行回应,其中必须要包含的内容为:

    Connection: Upgrade
    Sec-WebSocket-Accept: SzZpB9M8fiQtfbE4F1iAthSkY9k=
    Sec-WebSocket-Extensions: permessage-deflate
    Upgrade: websocket

    在完成了这些工作之后,客户端和服务端就可以进行通信了。

    二、websocket消息帧

    在完成了握手和消息头的回应之后,websocket收发消息是通过消息帧来进行的。结构如下:

    0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     |     Extended payload length continued, if payload len == 127  |
     + - - - - - - - - - - - - - - - +-------------------------------+
     |                               |Masking-key, if MASK set to 1  |
     +-------------------------------+-------------------------------+
     | Masking-key (continued)       |          Payload Data         |
     +-------------------------------- - - - - - - - - - - - - - - - +
     :                     Payload Data continued ...                :
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     |                     Payload Data continued ...                |
     +---------------------------------------------------------------+
    
    

    对于消息帧的解释,在这里参考知乎的一篇文章:websocket 协议帧 解析
    FIN:1 bit
    表示这是不是消息的最后一帧。 %x0:还有后续帧 %x1:最后一帧
    RSV1、RSV2、RSV3:1 bit
    扩展字段,除非一个扩展经过协商赋予了非零值的某种含义,否则必须为0
    opcode:4 bit
    解释 payload data 的类型,如果收到识别不了的opcode,直接断开。分类值如下: %x0:连续的帧 %x1:text帧 %x2:binary帧 %x3 - 7:为非控制帧而预留的 %x8:关闭握手帧 %x9:ping帧 %xA:pong帧 %xB - F:为非控制帧而预留的
    MASK:1 bit
    标识 Payload data 是否经过掩码处理,如果是 1,Masking-key域的数据即为掩码密钥,用于解码Payload data。协议规定客户端数据需要进行掩码处理,所以此位为1
    Payload len:7 bit | 7+16 bit | 7+64 bit
    表示了 “有效负荷数据 Payload data”,以字节为单位: - 如果是 0~125,那么就直接表示了 payload 长度 - 如果是 126,那么 先存储 0x7E(=126)接下来的两个字节表示的 16位无符号整型数的值就是 payload 长度 - 如果是 127,那么 先存储 0x7E(=126)接下来的八个字节表示的 64位无符号整型数的值就是 payload 长度
    Masking-key:0 | 4 bytes
    掩码密钥,所有从客户端发送到服务端的帧都包含一个 32bits 的掩码(如果mask被设置成1),否则为0。一旦掩码被设置,所有接收到的 payload data 都必须与该值以一种算法做异或运算来获取真实值。
    ws协议中,数据掩码的作用是增强协议的安全性。但数据掩码并不是为了保护数据本身,因为算法本身是公开的,运算也不复杂。除了加密通道本身,似乎没有太多有效的保护通信安全的办法,那么为什么还要引入掩码计算呢,除了增加计算机器的运算量外似乎并没有太多的收益(这也是不少同学疑惑的点)
    答案还是两个字:安全。但并不是为了防止数据泄密,而是为了防止早期版本的协议中存在的代理缓存污染攻击(proxy cache poisoning attacks)等问题
    Payload data:(x+y) bytes
    它是 Extension data 和 Application data 数据的总和,但是一般扩展数据为空。
    Extension data:x bytes
    除非扩展被定义,否则就是0
    Application data:y bytes
    占据 Extension data 后面的所有空间

    在下一章节中,我们就通过实际的代码来对于websocket的发送数据和接收数据进行详细的说明。

    相关文章

      网友评论

          本文标题:(二)gof websocket消息处理

          本文链接:https://www.haomeiwen.com/subject/mtuifltx.html