mqtt 协议里最简单的是 ping 协议吧 (心跳包), ping 协议是已连接的客户端发往服务端, 告诉服务端,我还"活着"

PINGREQ - PING request

fixed header format.

bit 7 6 5 4 3 2 1 0
byte 1 Message Type (12) DUP flag QoS level RETAIN
  1 1 0 0 x x x x
byte 2 Remaining Length (0)
  0 0 0 0 0 0 0 0

no variable header

no payload

response:   The response to a PINGREQ message is a PINGRESP message.

PINGRESP - PING response

fixed header

bit 7 6 5 4 3 2 1 0
byte 1 Message Type (13) DUP flag QoS level RETAIN
  1 1 0 1 x x x x
byte 2 Remaining Length (0)
  0 0 0 0 0 0 0 0

no variable header

no payload

------------------------------------------------------------------------ 华丽的分界线 ---------------------------------------

客户端会在一个心跳周期内发送一条PINGREQ消息到服务器端。两个字节,固定值。

服务器收到PINGREQ请求之后,会立即响应一个两个字节固定格式的PINGRESP消息。

周期定义在 心跳频率在CONNECT(连接包)可变头部“Keep Alive timer”中定义时间,单位为秒,无符号16位short表示。

ok ,上代码 :

固定头部 FinedHeader

    /// <summary>
/// Fixed header
/// </summary>
internal class FixedHeader
{
/// <summary>
/// Message type
/// </summary>
public MessageType MessageType { get; set; } /// <summary>
/// DUP flag
/// </summary>
public bool Dup { get; set; } /// <summary>
/// QoS flags
/// </summary>
public Qos Qos { get; set; } /// <summary>
/// RETAIN 保持
/// </summary>
public bool Retain { get; set; } /// <summary>
/// Remaining Length 剩余长度
/// 单个字节最大值:01111111,16进制:0x7F,10进制为127。
/// MQTT协议规定,第八位(最高位)若为1,则表示还有后续字节存在。
/// MQTT协议最多允许4个字节表示剩余长度。
/// 最大长度为:0xFF,0xFF,0xFF,0x7F,
/// 二进制表示为:11111111,11111111,11111111,01111111,十进制:268435455
/// </summary>
public int RemaingLength { get; set; } public FixedHeader() { } public FixedHeader(Stream stream)
{
if (stream.Length < )
throw new Exception("The supplied header is invalid. Header must be at least 2 bytes long."); var byte1 = stream.ReadByte();
MessageType = (MessageType)((byte1 & 0xf0) >> );
Dup = ((byte1 & 0x08) >> ) > ;
Qos = (Qos)((byte1 & 0x06) >> );
Retain = (byte1 & 0x01) > ; //Remaining Length
//var byte2 = stream.ReadByte();
var lengthBytes = ReadLengthBytes(stream);
RemaingLength = CalculateLength(lengthBytes);
} public void WriteTo(Stream stream)
{
var flags = (byte)MessageType << ;
flags |= (Dup ? : ) << ;
flags |= (byte)Qos << ;
flags |= Retain ? : ; stream.WriteByte((byte)flags); //byte 1
if (RemaingLength == ) //byte 2
stream.WriteByte();
else
{
do
{
int digit = RemaingLength & 0x7f;
RemaingLength = RemaingLength >> ;
if (RemaingLength > )
digit = digit | 0x80;
stream.WriteByte((byte)digit);
} while (RemaingLength > );
}
} internal static byte[] ReadLengthBytes(Stream stream)
{
var lengthBytes = new List<byte>(); // read until we've got the entire size, or the 4 byte limit is reached
byte sizeByte;
int byteCount = ;
do
{
sizeByte = (byte)stream.ReadByte();
lengthBytes.Add(sizeByte);
} while (++byteCount <= && (sizeByte & 0x80) == 0x80); return lengthBytes.ToArray();
} internal static int CalculateLength(byte[] lengthBytes)
{
var remainingLength = ;
var multiplier = ; foreach (var currentByte in lengthBytes)
{
remainingLength += (currentByte & 0x7f) * multiplier;
multiplier *= 0x80;
} return remainingLength;
}
}

消息父类: Message

    internal class Message
{
public FixedHeader FixedHeader { get; protected set; } public Message()
{
} public Message(MessageType messageType)
{
FixedHeader = new FixedHeader
{
MessageType = messageType
};
} public virtual void WriteTo(Stream stream)
{
} public static Message CreateFrom(byte[] buffer)
{
using (var stream = new MemoryStream(buffer))
{
return CreateFrom(stream);
}
} public static Message CreateFrom(Stream stream)
{
var header = new FixedHeader(stream);
return CreateMessage(header, stream);
} public static Message CreateMessage(FixedHeader header, Stream stream)
{
switch (header.MessageType)
{
case MessageType.CONNACK:
return new ConnAckMessage(header, stream);
case MessageType.DISCONNECT:
return null;
case MessageType.PINGREQ:
return new PingReqMessage();
case MessageType.PUBACK:
return new PublishAckMessage(header, stream);
case MessageType.PUBCOMP:
//return new MqttPubcompMessage(str, header);
case MessageType.PUBLISH:
//return new MqttPublishMessage(str, header);
case MessageType.PUBREC:
//return new MqttPubrecMessage(str, header);
case MessageType.PUBREL:
//return new MqttPubrelMessage(str, header);
case MessageType.SUBACK:
//return new MqttSubackMessage(str, header);
case MessageType.UNSUBACK:
//return new MqttUnsubackMessage(str, header);
case MessageType.PINGRESP:
return new PingRespMessage(header, stream);
case MessageType.UNSUBSCRIBE:
case MessageType.CONNECT:
case MessageType.SUBSCRIBE:
default:
throw new Exception("Unsupported Message Type");
}
}
}

两个枚举:

MessageType  (消息类型)

Qos (服务质量等级)

    [Flags]
public enum MessageType : byte
{
CONNECT = ,
CONNACK = ,
PUBLISH = ,
PUBACK = ,
PUBREC = ,
PUBREL = ,
PUBCOMP = ,
SUBSCRIBE = ,
SUBACK = ,
UNSUBSCRIBE = ,
UNSUBACK = ,
PINGREQ = ,
PINGRESP = ,
DISCONNECT =
} /// <summary>
/// 服务质量等级
/// </summary>
[Flags]
public enum Qos : byte
{
/// <summary>
/// QOS Level 0 - Message is not guaranteed delivery. No retries are made to ensure delivery is successful.
/// </summary>
AtMostOnce = , /// <summary>
/// QOS Level 1 - Message is guaranteed delivery. It will be delivered at least one time, but may be delivered
/// more than once if network errors occur.
/// </summary>
AtLeastOnce = , /// <summary>
/// QOS Level 2 - Message will be delivered once, and only once. Message will be retried until
/// it is successfully sent..
/// </summary>
ExactlyOnce = ,
}

ping 请求包:  PingReqMessage

响应包:         PingRespMessage

    internal sealed class PingReqMessage : Message
{
public PingReqMessage()
: base(MessageType.PINGREQ)
{
} public override void WriteTo(Stream stream)
{
FixedHeader.WriteTo(stream);
}
} internal class PingRespMessage : Message
{
public PingRespMessage()
: base(MessageType.PINGRESP)
{
} public PingRespMessage(FixedHeader header, Stream stream)
{
FixedHeader = header;
}
}

OK.

mqtt 协议之 PINGREQ, PINGRESP的更多相关文章

  1. MQTT 协议学习:007-Keep Alive 连接保活 与 对应报文(PINGREQ、PINGRESP)

    背景 keep alive 是 CONNECT 报文中可变头的一部分. 我们提到过 Broker 需要知道 Client 是否非正常地断开了和它的连接,以发送遗愿消息.实际上 Client 也需要能够 ...

  2. MQTT协议(一)

    MQTT(Message Queue Telemetry Transport),遥测传输协议,提供订阅/发布模式,更为简约.轻量,易于使用,针对受限环境(带宽低.网络延迟高.网络通信不稳定),可以简单 ...

  3. MQTT协议学习笔记

    1.前沿 万物联网的时代即将到来,物联网也由当初的概念开始进一步落实.随着无线网络技术飞速发展,各种设备都可以连接网络,实现远程控制.例如智能家居最近非常火爆,智能插座.智能LED灯.智能摄像头等.在 ...

  4. 物联网MQTT协议分析和开源Mosquitto部署验证

    在<物联网核心协议—消息推送技术演进>一文中已向读者介绍了多种消息推送技术的情况,包括HTTP单向通信.Ajax轮询.Websocket.MQTT.CoAP等,其中MQTT协议为IBM制定 ...

  5. Netty实现高性能IOT服务器(Groza)之手撕MQTT协议篇上

    前言 诞生及优势 MQTT由Andy Stanford-Clark(IBM)和Arlen Nipper(Eurotech,现为Cirrus Link)于1999年开发,用于监测穿越沙漠的石油管道.目标 ...

  6. MQTT协议-MQTT协议解析(MQTT数据包结构)

    协议就是通信双方的一个约定,即,表示第1位传输的什么.第2位传输的什么…….在MQTT协议中,一个MQTT数据包由:固定头(Fixed header). 可变头(Variable header). 消 ...

  7. MQTT协议笔记之连接和心跳

    前言 本篇会把连接(CONNECT).心跳(PINGREQ/PINGRESP).确认(CONNACK).断开连接(DISCONNECT)和在一起. CONNECT 像前面所说,MQTT有关字符串部分采 ...

  8. MQTT协议实现Eclipse Paho学习总结

    MQTT协议实现Eclipse Paho学习总结 摘自:https://www.cnblogs.com/yfliufei/p/4383852.html 2015-04-01 14:57 by 辣椒酱, ...

  9. 采用MQTT协议实现android消息推送(1)MQTT 协议简介

    1.资料 mqtt官网 http://mqtt.org/ 服务端程序列表 https://github.com/mqtt/mqtt.github.io/wiki/servers 客户端库列表 http ...

随机推荐

  1. tenda t402 家庭版 有线路由器

    使用快速向导: adsl(拨号)+用户名+密码 路由器后DMZ主机设置简单图解:http://wenku.baidu.com/view/94b9f0768e9951e79b8927ce.html  可 ...

  2. redis可编译

    redis-3.0.7 可编译 redis-3.0.7.tar.gz twemproxy-master.zip keepalived-1.2.19.tar.gz openssl-1.0.1s.tar. ...

  3. [转载]循规蹈矩:快速读懂SQL执行计划的套路与工具

    作者介绍 梁敬彬,福富研究院副理事长.公司唯一四星级内训师,国内一线知名数据库专家,在数据库优化和培训领域有着丰富的经验.多次应邀担任国内外数据库大会的演讲嘉宾,在业界有着广泛的影响力.著有多本畅销书 ...

  4. 【LabVIEW技巧】LabVIEW中的错误2

    前言 通过上一个文章的介绍,我们发现LabVIEW自带的错误管理依旧比较基础,如果需要对错误进行很好的管理,则需要进一步的进行程序编写. 用于在程序设计的过程中,为了保证程序的健壮性,我们需要 1.忽 ...

  5. Nginx集群配置与redis的session共享策略

    一.什么是Nginx? Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Ramb ...

  6. elasticsearch批量索引数据示例

    示例数据文件document.json(index表示在索引中增加或替换现有文档,create表示如果文档不存在则添加文档,delete表示删除文档): { "index": { ...

  7. linux命令(34):less命令

    1.命令格式: less [参数]  文件 2.命令功能: less 与 more 类似,但使用 less 可以随意浏览文件,而 more 仅能向前移动,却不能向后移动,而且 less 在查看之前不会 ...

  8. 196. Delete Duplicate Emails

    Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique ...

  9. 【JBPM4】判断节点decision 方法1

    JPDL <?xml version="1.0" encoding="UTF-8"?> <process key="decision ...

  10. 前端读者 | Web App开发入门

    本文来自互联网 自Iphone和Android这两个牛逼的手机操作系统发布以来,在互联网界从此就多了一个新的名词 - Web App(意为基于WEB形式的应用程序).业界关于Web App与Nativ ...