一 复习和目标

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\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

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来加深对协议的复习和补充。

WebSocket协议探究(三):MQTT子协议的更多相关文章

  1. WebSocket协议探究(序章)

    一 WebSocket协议基于HTTP和TCP协议 与往常一样,进入WebSocket协议学习之前,先进行WebSocket协议抓包,来一个第一印象. WebSocket能实现客户端和服务器间双向.基 ...

  2. WebSocket协议探究(一)

    一 复习和目标 1 复习 上一节使用wireshark抓包分析了WebSocket流量 包含连接的建立:HTTP协议升级WebSocket协议 使用建立完成的WebSocket协议发送数据 2 目标 ...

  3. 物联网学习笔记三:物联网网关协议比较:MQTT 和 Modbus

    物联网学习笔记三:物联网网关协议比较:MQTT 和 Modbus 物联网 (IoT) 不只是新技术,还是与旧技术的集成,其关键在于通信.可用的通信方法各不相同,但是,各种不同的协议在将海量“事物”连接 ...

  4. HTTP协议探究(三):HTTPS

    一 复习与目标 1 复习 代理:转发通信数据(一般协议不变,作为中间人,可对报文进行过滤修改) 网关:转发通信数据(协议改变,作为资源拥有者) 隧道:转发通信数据(协议不变,作为管道,不对报文进行过滤 ...

  5. MQTT协议探究(一)

    1 准备阶段 MQTT客户端:https://www.cnblogs.com/linzhanfly/p/9923577.html WireShark MQTT服务器(iot.eclipse.org) ...

  6. IOT设备通讯,MQTT物联网协议,MQTTnet

    一.IOT设备的特性 硬件能力差(存储能力基本只有几MB,CPU频率低连使用HTTP请求都很奢侈) 系统千差万别(Brillo,mbedOS,RIOT等) 如使用电池供电,电量消耗敏感 如果是小设备, ...

  7. TCP协议探究(一):报文格式与连接建立终止

    一 TCP:传输控制协议报文格式 1 TCP服务 提供面向连接.可靠的字节流服务 面向连接意味着两方通信,不支持多播和广播 可靠性的支持: 应用数据被分割成TCP认为最适合发送的数据块.由TCP传递给 ...

  8. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...

  9. 通信原理之IP协议,ARP协议 (三)

    把这三个协议放到一起学习是因为这三个协议处于同一层,ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息.数据链路层可以从ARP得到数据的传送信息,而从IP得到要传输的数 ...

随机推荐

  1. kill 一个名字 程序的所有进程

    ps aux | grep chrome | awk '{print $2}' | xargs kill -9

  2. Android:状态栏禁用时蓝牙多文件传输弹窗及进度显示

    一.蓝牙文件传输弹窗 Android原生蓝牙传输文件时,会弹出蓝牙文件接收的确认框且默认是以notification的形式显示在状态栏,当用户点击之后才会弹出一个dialog.那么当状态栏被禁用时,如 ...

  3. Linux系列之——tomcat 的开机自启动

    --未验证 每次开机都要启动tomcat,非常麻烦:通过直接修改系统文件,实现tomcat自启动: 1. 修改脚本文件rc.local:vim /etc/rc.d/rc.local 这个脚本是使用者自 ...

  4. ARM程序的RO段、RW段和ZI段 --Image

    Limit 含义了解RO,RW和ZI需要首先了解以下知识:ARM程序的组成此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别. ...

  5. React vs. Angular vs. Vue

    原文连接 历史 React是一个用于构建Web应用程序UI组件的JavaScript库. React由Facebook维护,许多领先的科技品牌在其开发环境中使用React. React被Faceboo ...

  6. Harbor 1.8.0 仓库的安装和使用

    安装的先决条件 硬件环境 1.CPU    至少2G,最好4G 2.内存    至少4G,最好8G 3.磁盘    至少40G,最好160G 软件环境 1.docker版本    17.03.0-ce ...

  7. Flutter运行报错 `kernel_snapshot for errors` 解决方案

    Flutter运行报错 `flutter kernel_snapshot for errors`解决方案 当你Flutter项目删除了dart文件如果遇到 target:kernel_snapshot ...

  8. git 提交大小超过100M

    #MsnDialog.ad, #MyMoveAd, #QQ_Full, #ad-SNSSplashAd, #ad6cn, #adBody07, #adLeftFloat, #adRightFloat, ...

  9. 居里先生的猜想 | 皮埃尔·居里诞辰160周年

    皮埃尔·居里(Pierre Curie)先生坐在桌前,手里把玩着一块小磁铁.忽然,一道闪念跃入脑海,他为自己这个大胆的想法激动不已,忍不住伏案疾笔书写起来.不远处,一位安静的青年女子温情脉脉地注视着他 ...

  10. python 优雅的解析 jsonp

    一段 jsonp 格式数据 mtopjsonpweexcb1({"api":"mtop.taobao.idle.recycle.nextspunav.get", ...