序
前几篇文章我们介绍了MQTT协议本身,虽然非常适合物联网项目,但是在项目实施的时候有诸多不便:mosquitto等开源产品可扩展性不佳、需要自己签发X509证书、认证与授权不灵活、MQTT服务需要自己运维等。所以,在实施物联网服务的时候,应该采用云端的托管服务,以便聚焦物联网业务,而不是为了基础架构和运维烦恼。
这次我们将通过百度开放云物联网服务IoT来体验一下云端的MQTT托管服务是一个什么样的体验。
背景
百度开放云物联网(IoT)服务是一个全托管的云服务,帮助建立设备与云端之间安全可靠的双向连接,以支撑各种类型的物联网项目,而无需考虑服务的运维。
使用物联网服务提供如下好处:
- 从设备到云端以及从云端到设备可靠地进行大规模消息传输。
- 对设备认证与权限管理,并保证数据安全传输。
- 支持多种语言开发,兼容主流硬件设备。
- 与大数据服务无缝对接,以数据分析驱动业务进步。
为了更好地支持设备与云端之间的互联互通,百度开放云物联网服务原生支持MQTT(Message Queuing Telemetry Transport)协议。MQTT是基于二进制消息的发布/订阅编程模式的消息协议,最早由IBM提出的,如今已经成为OASIS规范。与HTTP、CoAP、XMPP等协议相比,MQTT协议有以下的优势:
- MQTT基于TCP,在反控设备的时候比CoAP等基于UDP的协议更可靠,比如使用3G通讯的时候需要专门实现CoAP over TCP,否则反控很不稳定。
- MQTT异步Pub/Sub实现,好比发个短信,无需等待对方确认便可以继续,而不像HTTP、CoAP那样必须等待对方应答才能返回的同步模式。
- MQTT为物联网提供了许多体贴的设计,比如QoS,比如“遗言”等设计。
- MQTT是二进制格式,比XMPP更轻量级。
总之,通过支持轻量级可扩展的MQTT,百度开放云物联网服务非常适合需要低功耗和网络带宽有限的物联网场景,国外的公有云供应商如AWS、Azure、Bluemix等都以各种形式加入了对MQTT的支持。
使用物联网服务的参考架构如下:
为了保障安全,开放云物联网服务的MQTT通讯都是通过SSL加密的,确保消息不会被监听与篡改。
要使用百度物联网服务,请到这里申请测试。目前提供的是基于命令行的用户体验,可以参考入门指南配置Python环境并下载命令行工具。
运维体验
百度物联网服务分为运维人员体验和开发人员体验两部分。首先让我们来看运维人员体验。
首先需要创建IoT实例,以容纳多个设备、身份、策略等资源:
bce.py iot create-endpoint --endpoint-name "smart-project"
在实例下面可以创建一或多个设备:
bce.py iot create-thing --endpoint-name "smart-project" --thing-name "sensor-100"
成功创建设备后,系统返回username,是用来作为标识符与MQTT服务交互的。
下面进行权限管理,保证设备能够对特定的主题订阅发布消息。
首先需要创建一个或多个身份(Principal)来代表物联网服务中的认证主体。对于物联网服务,权限绑定在身份而不是设备上的,这样用户可以为每个设备创建不同的身份,或者设备共享一个身份,非常灵活:
bce.py iot create-principal --endpoint-name "smart-project" --principal-name "sensor-principle"
身份创建成功后,服务返回password。这里需要说明一下,这边的password其实是个密钥,只要能提供这个密钥,系统便会赋予相应的身份。换句话说,上面创建的sensor-100可以提供这个密钥以获得sensor-principle身份,sensor-200如果能够提供同样的密钥,系统也会把它辨识成同样的身份,拥有身份上面所对应的一切权限。
用以下命令把这个身份绑定在设备上:
bce.py iot attach-thing-principal --endpoint-name "smart-project" --thing-name "sensor-100" --principal-name "sensor-principle"
下面创建策略(Policy),以控制对消息主题的订阅发布等操作权限。比如,用于订阅和发布某公司B楼第5层的温度的主题,实现方式如下:
bce.py iot create-policy --endpoint-name "smart-project" --policy-name "b-5-temperature-policy" --topic="building-b/floor-5/temperature" --operation=PUBLISH --operation=SUBSCRIBE
创建策略成功后,便可以绑定到身份上,拥有这个身份的设备sensor-100便继承了对主题的订阅发布权限:
bce.py iot attach-principal-policy --endpoint-name "smart-project" --policy-name "b-5-temperature-policy" --principal-name "sensor-principle"
运维人员体验至此结束,物联网服务已经包含了一个设置好了访问权限的设备。
开发体验
下面我们看一下开发人员体验。
本质上开发人员只需要按照MQTT协议编程即可,具体的规范请参考http://mqtt.org/。实际上,由于MQTT是物联网的标准协议,有着丰富的客户端支持,比如Eclipse基金会提供的Paho支持Windows/Unix/Mac/Android/RTOS上C/C++/Java/Python/JavaScript/.Net语言的开发。
这里我们就以NetBeans开发环境编写Java应用为例。新建一个Java应用程序类型的Maven项目,右击“依赖关系”选择添加依赖关系,查询org.eclipse.paho,并加入对org.eclipse.paho.client.mqttv3的依赖,并在main函数中加入以下代码:
String endpoint = "smart-project";
String username = "smart-project/sensor-100";
String password = "Dm3yyvOHb7zt/uRWadfasdfMc+uDbf4j960=";
String topic = "building-b/floor-5/temperature";
// 创建SSL连接
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init((KeyStore)null);
TrustManager[] trustManagers = tmf.getTrustManagers();
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, trustManagers, null);
// 配置MQTT连接
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setUserName(username);
options.setPassword(password.toCharArray());
options.setSocketFactory(ctx.getSocketFactory());
// 创建MQTT连接
MqttClient client = new MqttClient(endpoint, "java-client");
client.connect(options);
// 发送消息
MqttMessage message = new MqttMessage();
message.setPayload("15".getBytes());
client.publish(topic, message);
client.disconnect();
把以上代码植入智能设备,便可以轻松安全地向云端发送消息了。从云端向智能设备发送控制命令也很直观,这里就不再赘述了。
可以看见,采用云端的托管物联网服务,把基础架构与运维交给云服务供应商,使得物联网项目实施高效便捷了许多。百度开放云物联网服务为物联网而生,不但提供了全托管的MQTT服务,在安全性与可扩展性方面也做下足了功夫,诚意十足。