zoukankan      html  css  js  c++  java
  • WebSocket协议探究(三):MQTT子协议

    一 复习和目标

    1 复习

    • Nodejs实现WebSocket服务器
    • Netty实现WebSocket服务器(附带了源码分析)
    • Js api实现WebSocket客户端

    注:Nodejs使用的Socket.io模块实现,Netty本身对WebSocket有一定的支持,所以这两种实现都相对容易理解,大家自己可以使用自己喜欢的语言实现(参考Nodejs版本,即不需要考虑过多的情况)。

    2 目标

    • 使用WebSocket协议进行发送Mqtt消息
    • 即Mqtt协议作为WebSocket协议的子协议进行通信

    注1:WebSocket协议内容不多,但是远远不止这么少。但是学习不要完美主义(即学到一样东西就想着一开始就把这样东西学透),学习要带着目的性。比如:我就是想弄懂为什么前端需要使用WebSocket协议才能发送Mqtt消息?WebSocket为什么需要HTTP协议来进行协议升级协商?HTTP协议为什么基于TCP协议?TCP协议是全双工的为什么HTTP协议不能全双工?等等......

    注2:协议目前学习了MQTT、TCP、HTTP和WebSocket,并不是现在学完了,以后就可以不再去学习这些,而是说对于现在的学习目的已经达到了,不需要再花费过多的精力罢了。

    二 WireShark抓包

    1 WebSocket连接

    • 请求升级协议:HTTP -> WebSocket(mqtt)
    # 省略无关头部
    Hypertext Transfer Protocol
    	GET /mqtt HTTP/1.1
    
    	Host: 103.61.37.192:8083
    
    	Sec-WebSocket-Version: 13
    
    	Sec-WebSocket-Protocol: mqtt
     # 子协议为mqtt
    	Sec-WebSocket-Extensions: permessage-deflate
    
    	Sec-WebSocket-Key: npQCPFw1Pc5G9vqjJyi90w==
    
    	Connection: keep-alive, Upgrade
    
    	Upgrade: websocket
    
    	
    
    
    • 响应成功
    # 省略无关头部
    Hypertext Transfer Protocol
    	HTTP/1.1 101 Switching Protocols
    
    	Connection: Upgrade
    
    	Content-Length: 0
    
    	Sec-Websocket-Accept: biw/vsujgvKx8B0bfoDnjuxHMgA=
    
    	Sec-Websocket-Protocol: mqtt
     # 确认子协议为mqtt
    	Upgrade: websocket
    
    	
    
    

    2 MQTT建立连接

    • 客户端 -> 服务器:CONNECT
      • 本来MQTT TCP连接可以通过分段或一次传输完成的WebSocket则分成了13次发送
    # 发送了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
    
    • 服务器 -> 客户端:CONNACK
    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) # 连接返回码
    

    3 MQTT的PINGREQ和PINGRESP

    • 客户端 -> 服务器:PINGREQ
    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
    
    • 服务器 -> 客户端 :PINGRESP
    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
    

    4 MQTT的SUBSCRIBE和SUBACK

    • 客户端 -> 服务器:SUBSCRIBE
    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
    
    • 服务器 -> 客户端 :SUBACK
    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 -> 成功
    

    5 MQTT的PUBLISH(Qos0)

    # 帧序号    数据                                                          
    # 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
    

    6 MQTT的DISCONNECT

    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协议探究(二)

    注2:MQTT其他报文就不做贴出来了,请自行测试。

    注3:协议的学习基本完成,后面结合Netty来加深对协议的复习和补充。

  • 相关阅读:
    Asp.net 程序连接orcle如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,
    Navicat 远程连接 Oracle11g 数据库报错 No listener 的问题
    springMVC中@DateTimeFormat 失效的处理
    单例设计模式中懒汉式线程安全的处理
    ajax同步请求
    vue.js在标签属性中拼接字符串
    vue.js进行遍历
    html页面之间的传值
    URL编码和解码的一个小问题(JS方法和JAVA方法)
    SolrJ的配置及使用
  • 原文地址:https://www.cnblogs.com/linzhanfly/p/10108094.html
Copyright © 2011-2022 走看看