注:Nodejs使用的Socket.io模塊實現,Netty自己對WebSocket有必定的支持,因此這兩種實現都相對容易理解,你們本身可使用本身喜歡的語言實現(參考Nodejs版本,即不須要考慮過多的狀況)。html
注1:WebSocket協議內容很少,可是遠遠不止這麼少。可是學習不要完美主義(即學到同樣東西就想着一開始就把這樣東西學透),學習要帶着目的性。好比:我就是想弄懂爲何前端須要使用WebSocket協議才能發送Mqtt消息?WebSocket爲何須要HTTP協議來進行協議升級協商?HTTP協議爲何基於TCP協議?TCP協議是全雙工的爲何HTTP協議不能全雙工?等等......前端
注2:協議目前學習了MQTT、TCP、HTTP和WebSocket,並非如今學完了,之後就能夠再也不去學習這些,而是說對於如今的學習目的已經達到了,不須要再花費過多的精力罷了。web
# 省略無關頭部 Hypertext Transfer Protocol GET /mqtt HTTP/1.1\r\n Host: 103.61.37.192:8083\r\n Sec-WebSocket-Version: 13\r\n Sec-WebSocket-Protocol: mqtt\r\n # 子協議爲mqtt Sec-WebSocket-Extensions: permessage-deflate\r\n Sec-WebSocket-Key: npQCPFw1Pc5G9vqjJyi90w==\r\n Connection: keep-alive, Upgrade\r\n Upgrade: websocket\r\n \r\n
# 省略無關頭部 Hypertext Transfer Protocol HTTP/1.1 101 Switching Protocols\r\n Connection: Upgrade\r\n Content-Length: 0\r\n Sec-Websocket-Accept: biw/vsujgvKx8B0bfoDnjuxHMgA=\r\n Sec-Websocket-Protocol: mqtt\r\n # 確認子協議爲mqtt Upgrade: websocket\r\n \r\n
# 發送了13個幀 192.168.1.46 103.61.37.192 WebSocket WebSocket Binary [FIN] [MASKED] 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0010 = Opcode: Binary (2) 1... .... = Mask: True .000 0001 = Payload length: 1 Masking-Key: 0c3cb539 Masked payload 1C # 幀序號 數據 # 1 Data: 10 -> Header Flags:Connect # 2 Data: 58 -> Msg Len:88 # 3 Data: 0004 -> Protocol Name Length: 4 # 4 Data: 4d515454 -> Protocol Name: MQTT # 5 Data: 04 -> Version:v3.1.1 # 6 Data: c2 # 1... .... = User Name Flag: Set # 用戶名 # .1.. .... = Password Flag: Set # 密碼 # ..0. .... = Will Retain: Not Set # 遺囑保留 # ...0 0... = Qos Level: 0 # .... .0.. = Will Flag: Not Set # 遺囑 # .... ..1. = Clean Session Flag: Set # 清除會話 # .... ...0 = (Reserverd): Not Set # 固定爲0 # 7 Data: 003c -> Keep Alive: 60秒 # 8 Data: 0011 -> Client ID Length: 17 # 9 Data: 6d 71 74 74 6a 73 5f 39 38 33 37 66 65 30 62 61 38 -> ClientId # 10 Data: 000b -> Username Length # 11 Data: 64656c696768742f776562 -> Username # 12 Data: 002c -> Password Length # 13 Data: 45396a4d58416c35523939596b48756350506c3377545468... -> Password
WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0010 = Opcode: Binary (2) 0... .... = Mask: False .000 0100 = Payload length: 4 Data (4 bytes) Data: 20 02 00 00 # 20 -> Header Flags:CONNACK # 02 -> Msg Len:2 # 00 -> Acknowledge Flags: 0x00 # 鏈接確認標誌 # 00 -> Return Code: Connection Accepted (0) # 鏈接返回碼
WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0010 = Opcode: Binary (2) 1... .... = Mask: True .000 0010 = Payload length: 2 Masking-Key: 0657364e Data (2 bytes) Data: c000 # C0 -> Header Flags: 0xC0 (Ping Request) # 00 -> Msg Len: 0
WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0010 = Opcode: Binary (2) 0... .... = Mask: False .000 0010 = Payload length: 2 Data (2 bytes) Data: d000 # D0 -> Header Flags: 0xD0 (Ping Response) # 00 -> Msg Len: 0
WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0010 = Opcode: Binary (2) 1... .... = Mask: True .000 0001 = Payload length: 1 Masking-Key: d0f56152 Data (1 byte) Data: 82 # 幀序號 數據 # 1 Data: 82 -> Header Flags: Subscribe Request # 2 Data: 0b -> Msg Len:11 # 3 Data: a5b2 -> Message Identifier: a5b2 # 4 Data: 0006 -> Topic Length: 6 # 5 Data: 2f 57 6f 72 6c 64 -> Topic:/World # 6 Data: 00 -> Requested QoS:0
WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0010 = Opcode: Binary (2) 0... .... = Mask: False .000 0101 = Payload length: 5 Data (5 bytes) Data: 9003a5b200 # 90 -> Header Flags: Subscribe Ack # 03 -> Msg Len: 3 # a5b2 -> Message Identifier:a5b2 # 00 -> 成功
# 幀序號 數據 # 1 Data: 30 -> Header Flags: Publish Message # 2 Data: 0d -> Msg Len: 13 # 3 Data: 0006 -> Topic Length:6 # 4 Data: 2f 57 6f 72 6c 64 -> Topic:/World # 5 Data: 68 65 6c 6c 6f -> Message:hello
WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0010 = Opcode: Binary (2) 1... .... = Mask: True .000 0010 = Payload length: 2 Masking-Key: d70088a5 Data (5 bytes) Data: e000 # e0 -> Header Flags: Disconnect # 00 -> Msg Len: 0
注1:MQTT報文格式請參考MQTT協議探究(一) MQTT協議探究(二)shell
注2:MQTT其餘報文就不作貼出來了,請自行測試。api
注3:協議的學習基本完成,後面結合Netty來加深對協議的複習和補充。服務器