WebSphere MQ Telemetry Transport 简介
WebSphere MQ Telemetry Transport (MQTT) 是一项异步消息传输协议,是 IBM 在分析了他们的客户在其业务中使用 WebSphere MQ 消息传递的情况(包括通过它传递数据)之后专门为物联网所定制的重要的轻量级消息传输协议。IBM 发现,数据经常是在企业外部的远程位置生成的,而且数据在从远程位置到达企业之前通常要经历一个复杂的过程。这时往往将数据人工输入计算机,然后只能通过 WebSphere MQ Enterprise 消息传递系统传输。而 MQTT 的开发将 WebSphere MQ 消息传递的应用范围延伸到这些远程位置。
WebSphere MQ 遥测传输 (MQTT) 是轻量级基于代理的发布 / 订阅的消息传输协议,设计思想是开放、简单、轻量、易于实现。这些特点使它适用于受限环境。例如,但不仅限于此:
- 网络代价昂贵,带宽低、不可靠。
- 在嵌入设备中运行,处理器和内存资源有限。
该协议的特点有:
- 使用发布 / 订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
- 对负载内容屏蔽的消息传输。
- 使用 TCP/IP 提供网络连接。
- 有三种消息发布服务质量:
- "至多一次",消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
- "至少一次",确保消息到达,但消息重复可能会发生。
- "只有一次",确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
- 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。
- 使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制。
推送服务
推送服务表现为客户端能自动收到服务器发送过来的数据和信息。其目的都是为了给最终客户方便有效地发送最新消息或者数据。而且推送的模式对以前的数据访问方式提供很好的补充和发展。首先,给最终用户带来了很好的使用体验,可以实时的获取自己感兴趣的信息,与此同时,给服务器端的应用商,也提供了更为便捷和主动的数据,服务发布方式,使得应用商能够控制信息发布的频率和时间,从而能更精准的投送的最终用户。
推送服务本质上是服务器主动将消息,数据发送到客户端,而不是客户端主动去服务器请求数据。这种推送只需要客户端与服务器连接后,在有数据的情况下,服务器端马上将数据发送到客户端。这里的客户端可以是多种类型的,比如比较常见的浏览器,移动应用等等。
推送服务的实现方式大致可分为 Poll 和 Push 模式。
- Poll 模式
Poll 模式,本质上是"伪推送"模式,或者叫短轮询模式。是客户端通过设定固定的时间间隔,然后在时间间隔到达后,客户端主动向服务器发送请求,去更新是否有新数据。这种模式的特点是,客户端需要不停的轮询访问服务器获取信息,其时间间隔设定无法真正体现实时推送,间隔太长容易导致信息不能实时的更新,间隔太短,客户端需要发送很多不必要的连接请求,耗费很多网络流量和服务器开销。比如在移动终端上,此类模式会在设备电能消耗,网络流量使用方面存在很多瓶颈。
- Push 模式
Push 模式,一般意义上使用长连接去建立一个客户端到服务器的双向数据通道,只要在连接建立后,一旦一方有数据更新,就可以马上通过双向的数据通道向对方发送数据,平时在没有数据时,通过一些心跳等机制维持通道连接。Push 模式的特点,简化的客户端的开发,数据能近乎实时的发送到对方。但其在设备资源消耗和网络流量控制方面,根据其使用的不同协议会有很大不同,特别是在移动推送领域,长连接对移动设备电量和网络流量的消耗要求较高。同时,由于需要维护长连接,对服务器在高并发连接的处理能力和性能也有很高要求。
移动推送服务
推送服务在很多领域都有发展,但特别在移动领域,由于其飞速发展,给推送服务带来了很多新的机遇和挑战。首先,移动市场规模越来越大,终端种类和数量越来越多,使得推送服务的的重要性越来越凸显;其次,传统的"伪推送"模式已越来越不能满足其需要,需要发展新的推送的技术,这促使了很多新的协议和框架的出现;但是,由于移动领域的终端设备和网络情况的特点,对推送的协议和框架又提出了新的挑战,比如:移动终端的计算和存储资源的限制,移动终端的电量消耗的限制,移动网络流量和成本的控制等等。主流的移动推送解决方案如下:
- SMS 短信
作为传统的消息通讯,在新型移动环境下,在网络成本方面的考量使其地位有逐渐边缘化的趋势。
- HTTP 轮询
使用定时的 HTTP 轮询方式,及客户端在一定的时间间隔里去重复向服务器请求数据更新,属于"伪推送",由于其协议复杂冗余,轮询间隔的不准确,耗费了不必要的流量,增加了终端用户网络成本等因素,现有的这种方式已经不适合做移动推送服务。
- XMPP
XMPP 是基于 XML 的通讯协议,此协议已基本上完成了标准化,成熟,强大,可扩展性强。但正是由于其协议复杂,冗余的设计,成为其在移动设备上短板,比如协议的复杂带来其协议栈的耗电增加,冗余的设计使得网络流量偏大,用户成本增加。
- 私有厂商协议和平台
私有厂商推出的推送服务,由于其协议私有,其传输效率和质量上无法量化和考证,而且还往往无法实现跨平台推送。同时,有些厂商提供的消息服务器不具备公开性,导致在用户数据安全性特别是服务器掌控方面存在担心。
IBM 基于 WebSocket 的 MQTT 跨平台推送服务方案
IBM 通过对现有移动推送平台比较之后,对其中存在的问题和缺陷做了很好的分析。这些问题集中体现在如下方面:
- 在网络方面
如何适应现有网络的不可靠,很好的保障数据发送可靠性
如何降低网络流量,从而节省网络成本
- 在移动设备方面
如何降低对设备能力的要求,特别是适应计算和存储弱的设备
如何降低对设备电量的消耗,满足设备电源能力的不足
如何降低平台依赖性,真正实现跨移动设备平台
- 在数据方面
缺少对数据安全性的保障,特别是对服务器的掌控
缺少对大量数据的监测,优化
IBM 针对上面问题,结合 MQTT 和 WebSocket,提出了更智慧的移动推送服务解决方案。
图 1. IBM 移动推送服务解决方案
方案中,服务器端使用 WebSphere MQ 作为 MQTT 的 Server,在移动设备中嵌入 MQTT 的客户端,并通过客户端建立到服务器的双向数据通道,然后在后台来自不同应用的数据通过 WebSphere MQ 推送到移动终端。那么,这样的解决方案,会有什么特点能够很好的解决和优化上面关于业界移动推送服务解决方案中存在的普遍问题,或者说此方案有什么自身的优势。
- 移动设备
能在 8bit 位处理器上很好的运行 C /JavaScript/Java 的 client 库分别只有 30/75/100KB
在移动设备上耗电率低,大约只需要 HTTP 的一半
通过使用基于 WebSocket 的 MQTT 客户端 JavaScript API,符合 Hybrid 开发潮流,只要设备的浏览器支持 WebSocket,就能很轻松实现多移动平台的跨越
- 很好的适应各种复杂网络,特别是受限网络
预期并适应频繁的网络中断,能应对低速、低质量的网络
压缩优化过后的协议,可以有效降低网络流量,从而节约网络成本
完成同样的数据通信,MQTT 只需要 HTTP 约 1/4 得数据流量
- 发布 - 订阅的消息通信协议,允许一条消息只发布一次,便可被多个消费端(应用程序 / 设备)所接收
实现系统间松耦合,简化开发,方便扩展,整合。
- 提供灵活便捷的系统整合能力
使用 MQ,MB 提供可靠系统内系统整合和通信
Cast Iron 强大的系统间整合带来巨大的灵活性
- 提供丰富的安全性
使用 SSL 提供的认证和加密来保证传输安全性
通过 JAAS 接口提供的身份认证
OAM 用于资源层面的授权
- 强大的性能提高系统的高可靠性
高连接数下系统低计算资源使用
高连接数下系统高信息处理速度
- 提供多种消息服务质量,满足不同场景需求
0 :消息最多被传递一次,比如一般类广告,通知
1 :消息会被传递但可能会重复传递,比如账户余额通知
2 :消息保证传递且仅有一次传递,比如交易支付批复通知
应用场景
本文是通过介绍使用 WebSphere MQ Telemetry 以及其 SDK 组件中自带的 MQTT 基本客户端(WebSocket API)实现一个 iOS 设备的推送应用场景,来使读者对使用基于 MQTT 协议的 WebSphere MQ Telemetry 来构建物移动推送服务解决方案有进一步的理解,并能够自己动手开发相应的解决方案。
该方案通过 WebSphere MQ Telemetry 自带的 MQTT 基本客户机 WebSocket JavaScript API 来实现客户端到服务器的连通。实现的场景如下:
- Mobile 用户相互通讯(文本,语音,图片)
- 后台应用向 Mobile 用户推送相关信息(广告,通知等等)
图 2. 移动推送服务场景
开发步骤及流程
整个开发会涉及到移动端开发和服务器端配置,以下将会分别介绍。
Note:开发工具使用 Worklight,Xcode,WebSphere MQ Explorer。
客户端开发
Worklight 平台为开发基于 Web 技术的手机客户端 App 提供了一套完整的解决方案,从开发、部署、测试到发布均可在这个平台上完成。App 用 HTML,CSS 和 Javascript 写成,之后被扩展成桌面的(Windows,Mac,Linux),互联网的(Facebook 等),本地移动设备上的(iOS,Android,RIM 和 Windows Phone)应用程序。开发者还能把一些流行的 Javascript 构架如 jQuery Mobile,Sencha 和 Dojo 整合到 Worklight 中。而且 App 的本地运行时也能用本地代码来编写和修改。
MQTT WebSocket JavaScript API 的功能描述如下:
- Connect 连接
MQTT 客户端负责向 MQTT 服务器发起连接操作,并开始计时,在超时期里接收到正确连接响应,则连接成功,负责连接超时。任何数据的发送或者收到,都将启动新的超时计时,在整个超时完成后没有数据的发送或者接收时,发送心跳以维持连接状态。
- DisConnect 断开连接
MQTT 客户端或者服务器发起连接断开命令。在发出连接断开命令后,开始超时计时,在超时内成功收到断开响应,双方设置其相应连接状态为断开;超时后尚未成功接收响应,则开始重发连接命令,直到重发次数到达系统设置上限。否则,设置对应原因。
- Subscribe 订购
在双方连接建立后,MQTT 客户端发送订购消息,来订购主题,并设置相应质量服务级别,在接收到订购确认后,自动接收在此主题上的任何消息。
- UnSubscribe 取消订购
在双方连接建立后,MQTT 客户端发送取消订购消息,来取消订购主题,在接收到取消订购确认后,在原来主题上的任何消息将不再推送到此客户端。
- Publish 发布
在双方连接建立后,MQTT 客户端将业务数据放入发布消息的消息体中,通过发布消息,发布在某主题上,此消息按照不同的消息服务质量级别,发布到不同的订购者客户端。
- Will 主题和消息
在 MQTT 客户端连接时设置,设定在自己连接中断后,自动往 Will 主题上发送的通知消息。
- 在 Worklight Studio 中新建 Worklight Project,在工程名中填入 WebSocketMQTT,然后选择 Hybrid Application,点击下一步,在应用名中填入 WebSocketMQTTApp,点击完成。
图 3. WorkLight 工程
- 在工程上单击右键,选择新建 Worklight Environment。Project 选择刚生成的 WebSocketMQTT,Application 选择刚生成的 WebSocketMQTTApp,然后在 Mobile 中选择"iPad"选项框。最后点击完成。
图 4. 新建 Worklight Environment
然后在工程中就生成的为 iPad 开发的模板。
图 5. iPad 开发模板
- 将 MQTT 的基于 WebSocket 的 Client API 拷贝到 iPad 下的 js 文件夹。
图 6. 拷贝 MQTT Client 的 JS 库文件
- 从本文附件中导入并替代展现页面 WebSocketMQTTApp.html 到 common 文件夹。
图 7. 替换原有展现页面
然后在 application:WebSocketMQTTApp 上右键,选择 Run As -> Build All and Deploy
- 在 iPad 模板图标上右键,选择 Run As -> Xcode project。
图 8. 打开 Xcode Project
在 Xcode 里,在 Build 成功后,选择配置过的 iOS 设备安装。
服务器开发和配置
安装 WebSphere MQ 7.5.0.1 版本,在安装过程中选择 Telemetry 组件,安装完后打开 WebSphere MQ 管理界面 WebSphere MQ Explorer。
- 打开 WebSphere MQ Explorer
图 9. WebSphere MQ Explorer
- 在 Queue Managers 上右键,选择新建 Queue Manager,输入 Queue Manager 名称,然后 Next 直到 Finish。
展开新创建的 Queue Manager,点击 Telemetry 并在右边的窗口中,选择 Define sample configuration...
图 10. 定义 Telemetry 服务
图 11. 配置 Telemetry
- 在配置部署后,会在 Services 中创建并启动服务:
SYSTEM.MQXR.SERVICE
同时展开 Telemetry 后在 Channels 里创建了一个接受 MQTT 连接的 PlainText 通道,端口默认是 1883。图 12. 支持 MQTT 连接的通道
- 最后为了测试数据的收发,可以打开 WebSphere MQ 自带的测试工具:MQTT Client Utility。
图 13. MQTT Client Utility 工具
服务器端的配置就完成了。
部署和验证
本文将通过模拟移动推送服务中的 2 个基本场景来验证。
- 两个 iPad 设备通讯模拟 Mobile 用户相互通讯
- MQTT Client Utility 向 iPad 发送消息模拟后台应用向 Mobile 用户推送相关信息
- 在两台 iPad 上安装我们刚刚开发的 App,并配置如下参数:
- Server:WebSphere MQ 的安装机器的 IP
- Port:在 WebSphere MQ 里配置的 MQTT 的通道的端口号,默认是 1883
- Client ID:页面会生成一个默认的,也可以自定义
- Topic Name:用于发布或者订购的主题,模拟通讯时,每个客户端有固定的主题,比如:iPad A 主题为 iPadA,iPad B 的主题为 iPadB。在通讯时每个客户端订购自己的主题接收别的客户端发送来的消息,同时给别的客户端的主题发送消息。
- QoS:质量服务等级
启动 App 后,在填写 Server,port 和 Client Id 后,点击连接(Connect),然后分别在订阅的 Topic Name 中填写自己要监听的主题:iPadA 或者 iPadB。最后,在发布 Publish 的 Topic 中填入要对话的对方的主题:iPadB 或者 iPadA,输入想发送的信息后,点击发送就可以开始两个 iPad 之间的通讯了。这里只是简单展现,除了文本通讯还可以实现语音,文件,照片通讯分享等。
图 14. iPadA
图 15. iPadB
通过以上两个截图,验证了两个 iPad 通过基于 WebSocket 的 MQTT 协议,实现了通讯,相互给对方发送了消息。
Note: 在 App 部署到 iPad 上后,如果 WorkLight 的服务器更换了,修改应用的 WorkLight Server 地址如下
图 16. 应用的 WorkLight 服务器地址
- 为了模拟服务器端应用向移动终端推送消息,采用 JMS 模式通过 WebSphere MQ 向终端推送一条数据。
- Topic Name:iPadPush
- Message:This is message from backend system application.
后端采用 JMS 方式发送数据
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;
import com.ibm.mq.jms.MQConnectionFactory;
public class JMSSender {
private Connection conn;
private Session sess;
private MessageProducer sender;
public static void main(String[] args) {
JMSSender jmsSender = new JMSSender();
jmsSender.createSender();
jmsSender.closeSender();
}
private void closeSender() {
try {
sender.close();
sess.close();
conn.close();
System.out.println("JMS Sender closed");
} catch (JMSException e) {
e.printStackTrace();
if (e.getLinkedException() != null) {
e.getLinkedException().printStackTrace();
}
}
}
private void createSender() {
MQConnectionFactory connFact = new MQConnectionFactory();
try {
// We are connecting to queue manager using client mode
connFact.setQueueManager("XRNEW");
connFact.setHostName("localhost");
connFact.setPort(1414);
System.out.println("Model"+connFact.getTransportType());
//connFact.setTransportType(1);
System.out.println("Model"+connFact.getTransportType());
conn = connFact.createConnection();
sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
sender = sess.createProducer(sess
.createQueue("queue://iPadA/iPadPush"));
Message msg = sess.createTextMessage(
"This is message from backend system application.");
msg.setJMSExpiration(10000);
sender.setTimeToLive(10000);
sender.send(msg);
System.out
.println("JMS Sender started and published message to topic iPadPush");
} catch (JMSException e) {
e.printStackTrace();
if (e.getLinkedException() != null) {
e.getLinkedException().printStackTrace();
}
}
}
}
图 17. 终端接收后端推送的消息
结束语
本文通过介绍使用 WebSphere MQ Telemetry 以及其 SDK 组件中自带的 MQTT 基本客户机的 WebSocket JavaScript API 开发一个 App,并通过实现通用的移动推送服务应用场景来使读者对使用基于 MQTT 协议的 WebSocket JavaScript API 来构建移动推送服务解决方案有进一步的理解,并能够自己动手开发相应的推送解决方案。