MQTT协议及拓展

来源:互联网 发布:网络施工系统报价清单 编辑:程序博客网 时间:2024/05/17 06:19

转载自:http://blog.wuzx.me/archives/102

MQTT协议及拓展

最近在折腾Android的推送,看到相关资料说可以用MQTT协议实现。所以就去查相关的资料,并展开相关知识了解,折腾了几天。

什么是MQTT协议


MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议。

MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性
1、使用发布(Publish)/订阅/(Subscribe)消息模式,提供一对多的消息发布,解除应用程序耦合

2、对负载内容屏蔽的消息传输

3、使用TCP/IP提供网络连接

4、有三种消息发布服务质量
“至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
“至少一次”,确保消息到达,但消息重复可能会发生。
“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。

5、小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量

6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制

参考百度百科MQTT

  • 简单的说MQTT协议是一个轻量级的即时通讯协议
  • 因为它被运用在一些硬件和网络不太好的环境,所以它对设备的要求不会太高,以适应艰难的环境。
  • 同时要保证信息传递的质量,所以有三种发布质量模式(QoS
  • 它原生条件下是基于TCP/IP的的应用层协议
  • 屏蔽了消息传输的具体数据交互格式。也就是不用关心底层是怎么传输的,数据用的是什么格式来传输的
  • 在物联网领域(IoT,Internet of Things)未来会有大发展

MQTT协议的实现


MQTT协议的实现,自然要分为客户端(Client)和服务端(Broker)。服务端也被称为代理,Broker。

在MQTT的官网也给出了一些客户端的编程库和服务端的实例。

服务端,或者叫代理(Broker),有很多,见下图。 broker

这些服务端有重有轻,有些是开源的,有些是企业级公司的收费产品。
像有些是IBM的一些产品框架,是要收费的。

当然也有一些开源的轻量级Broker,还有Apache的一些开源产品。

MQTT over WebSocket


“XXX over yyy” 的意思是在yyy的基础上实现XXX。

比如MQTT over WebSocket是指在WebSocket的基础上实现MQTT协议。

前面在说特点的时候,原生的MQTT协议应该是在运输层 TCP/IP协议的基础上的应用层协议。单独来看,WebSocket也是应用层的一个协议,是在TCP的基础上的一个全双工通道通信。 但是为了能在浏览器(浏览器只支持WebSocket这种全双工应用层协议,客户端用js实现,现在大部分浏览器都支持)上实现MQTT协议,就把WebSocket协议当做传输层的TCP/IP的角色,让MQTT跑在WebSocket协议上。

虽然MQTT基因层面选择了TCP作为通信通道,但我们添加个编解码方式,MQTT Over Websocket也可以的

参考MQTT协议笔记之mqtt.io项目Websocket协议支持

类似的跑在别的协议之上的协议的实现还有很多,尽管两者协议在性质上是平级的,都是应用层的协议

当然Broker也要能支持这种模式。有些Broker是可以接受跑在WebSocket上的MQTT协议的实现,有些则不支持,只支持原生在TCP协议基础上的实现。

所以这种的服务端就不能被JS实现的客户端连接。 服务端支不支持WebSocket的这种模式,可以看Broker的介绍里有没有说。

客户端(Client)除了JS的实现,其他的基本都是在TCP/IP协议基础上的,JS的实现是应该在浏览器上的,所以要在浏览器已实现的协议上实现MQTT协议,而WebSocket是最符合的。

这个模块先讲到这,下面内容还会回来用到。下面先讲个Broker的实例

一个Broker实例


说了这么多,看个实例 这里有个叫Mosquitto(这不是蚊子吗?蚊子是mosquito) Mosquitto

是一个开源的MQTT v3.1 Broker 这个Broker只有几百k,貌似是MQTT协议的创始人用C写的,非常精简,功能也非常强大。网上有朋友测过,可以承受20000人同时在线,自己还没测过,有空可以测一下。并且这个服务端有提供网桥功能。大概的意思是可以把服务器连在一起吧

Mosquitto 启动的时候有一个配置文件,在这个配置文件里可以设置一些参数,通过这些参数设定连接的一些条件和机制,比如timeout相关的和安全相关的认证机制。启动之后,服务器就可以开着,然后就通过客户端实现消息的发布(Publish)和订阅(Subscribe)

Eclipse有一个开源项目叫Paho,就是一个实现MQTT协议客户端的项目,它实现了好多语言的客户端的封装(甚至有嵌入式),还有一些工具(utilities)只要按照它的实例开发,很方便,并且文档很全。

paho

再次感谢开源项目,OpenSource精神

所以Android要实现推送,这里有现成的客户端。服务器就用Mosquitto,基本就差不多了。不过我还没亲测大用户量的情况。

关于Mosquito的使用,比如参数配置,还有客户端的实例编程,先不具体放代码,换一篇单独详细介绍。

WebSocket–TCP proxy


在我的项目中,Android打算用前面说的架构实现推送,就是Broker用Mosquitto,客户端用Paho的Android Client。但是Mosquitto是不支持Websocket的,所以Web端要实现推送就不能用同一个服务器。(原因前面节讲过了)(之前不知道,我试了好久WEB端上用JS连接Mosquitto,就是连不上,然后客户端打出错误代码和信息,在Google上查了很久,才知道不支持Websocket。也查到了下面的一种代理方法来实现)

所以如果要实现Web的推送,要么就单纯在WebSocket上实现消息传递,现在的一些Web服务器都有实现这个,比如Tomcat7以后就有Websocket编程接口。但是这样推送服务端就有两个,貌似不是很统一。

其实要MQTT服务器实现基于Websocket的连接也不是不可以。

  • 一种方法就是重写MQTT的服务端,加一些代码,使之支持Websocket。其实就是在中间加了一个中间件,使之能接受到Websocket的连接,并将MQTT协议的数据编解码放入Websocket中。MQTT协议实现可共享原来的基础逻辑,调用原服务器的逻辑。

一套服务端程序,同时提供若干种协议供终端选择。其实,一台MQTT Broker中间件服务器,可以绑定多个端口,一个面向纯TCP的1883端口,一个面向Websocket的80/8080端口,共享基础逻辑,面向不同协议。

但是这个方法在Mosquitto这个Broker上不好实现,因为这个用C写的,难度有点大。

有另一个MQTT的Broker是用Java写的叫Moquette(不要看错,和Mosquitto有点像)。它是一个Jar包,可以直接跑jar包,也可以写入自己的程序跑。所以添加一些代码相对比较容易,又因为是Java,编程接口和库比较丰富。但是前提是你能看懂Moquette的源码。

下面继续参考聂永的博客,里面有Java的实现。但他的MQTT服务器不是Moquette,所以代码什么的不完全一样。但原理是一样的。所以仅供参考。

参考MQTT协议笔记之mqtt.io项目Websocket协议支持

  • 另一种方法是做WebSocket–TCP proxy。从前端的Websocket的连接代理至后端的MQTT服务器。例如 mod_websocket,是一个轻量级Web服务器(lighttpd)的代理Websocket到TCP的模块。

原理图如下WebSocket--TCP proxy

简单的理解就是浏览器用WebSocket协议跟前端的服务器连接,而前端的服务器用TCP协议和后端的MQTT服务器连接。然后浏览器在Websocket的连接之上传递的内容,经过代理转到后端的MQTT服务器。

中间的代理剥掉了承载MQTT协议的Websocket协议外壳,然后把内容经过TCP包裹发给了后端的MQTT服务器

其实以上过程就是一个反向代理,在网络中很常见的手法。什么是反向代理,请自行查询资料。


综上这两种方法都可以让不支持Websocket的MQTT的Broker实现和Web端的JS的Client通信。

因为现在的网络架构Web服务器的第一层一般都会用Nginx实现反向代理,所以我应该会选择第二种方法。用Nginx实现Websocket–TCP代理,具体实现还没去研究,等搞定了放在反向代理的一篇博客里好了。

但就业务逻辑来讲,这么做的目的是为了Android的推送和Web的推送实现服务端的统一。如果Web的推送不用MQTT协议也是可行的,直接在Websocket上实现,前面也提过了。

Mosquitto的运用的自己的完整例子,后续使用时再做总结。

如有不对的地方,欢迎交流。 (完)


0 0