消息队列MQTT接入(物联)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MQTT接入(物联)
MQTT接入简介
1.MQTT介绍
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。

该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。

2.MQTT接入优势
目前我们的消息队列服务已经支持了tcp和http的方式,并且用户面极广,而对于近几年新起来的物联网行业,我们的消息服务也提供了最大化的支持。

目前消息队列服务已经在多家汽车企业和多家视频网站企业使用
,目前我们的在mqtt方面的优势主要在于三点:
1.稳定性高,延时低,这个主要得益于我们的消息队列服务,通过双十一的磨砺。

我们的消息队列服务稳定性得到极大提高并且时延极低
2.上手难度低,目前我们的整个mqtt接入层全面支持已经开源的mqtt客户端sdk,用户不管是用哪种语言的客户端,都能够无差别地"享受"我们的消息队列带来的便利和快捷。

3.开发运维成本低,目前鉴于开源的mqtt sdk以及我们提供的后台消息服务,用户可以容易快捷地开发出各种消息服务。

3.MQTT接入应用场景
所有支持和使用mqtt协议的应用,都可以使用我们的消息队列服务,例如:物联网,车联网等相关业务。

4.MQTT接入说明
目前我们提供了mqtt java版的测试demo,但是不仅限于java,开源的mqtt sdk所有版本都支持,用户可以放心使用,具体的使用方法,请参考相关测试demo
MQTT域名
目前,MQTT各Region域名如下:
Java
MQTT收发消息
本文主要描述如何在Java环境下使用MQTT协议收发MQ消息。

1.环境准备
在Java环境下使用MQTT协议收发MQ消息,请确保完成以下准备工作。

(1)在工程POM文件添加MQTT JAVA客户端的Repository。

<repositories>
<repository>
<id>Eclipse Paho Repo</id>
<url>https:///content/repositories/paho-releases/</url>
</repository>
<repository>
<id>snapshots-repo</id>
<url>https:///content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
(2)在工程POM文件添加MQTT JAVA客户端的依赖。

<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.0.1</version>
</dependency>
(3)在Java Classpath下添加配置文件user.properties。

请参考以下说明将配置文件修改成您自己的配置。

###请配置好以下字段,结合代码运行,即可了解用法。

AccessKey=your AccessKey
SecretKey=your SecretKey
###假设你在控制台申请的topic为X,申请的ProducerId为Y,申请的ConsumerId为Z。

Topic=X
2.MQTT发送消息示例代码
您可以按以下说明设置相应参数并测试MQTT消息发送功能:
###Y为在MQ控制台申请的ProducerId。

ProducerId=Y
###这个对应设备的clientId,M为设备号,Z为在MQ控制台申请的ConsumerId,M只要在Z下面保证唯一就可以,无需在控制台申请或创建。

如果要点对点发送消息给设备M,那么只需要发送消息topic为X/p2p/Z@@@M,详见3.MQTT Demo的代码。

ConsumerId=Z@@@M
###公测环境的mqtt地址
broker=tcp://:1883
###公测环境的http地址
url=/
package com.alibaba.ons.demo;
import java.io.IOException;
import java.util.Properties;
import com.aliyun.openservice.ons.mqtt.demo.MqttDemo;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.SendResult;
public class ProducerClient {
public static void main(String[] args) {
Properties properties=new Properties();
try {
properties.load(MqttDemo.class.getClassLoader().getResourceAsStream("user.properties"));
} catch (IOException e) {
e.printStackTrace();
}
properties.put("ProducerId", properties.get("ProducerId").toString().split("@@@")[0]);
Producer producer = ONSFactory.createProducer(properties);
//在发送消息前,必须调用start方法来启动Producer,只需调用一次即可。

producer.start();
Message msg = new Message(
//Message Topic
properties.getProperty("Topic"),
//Message Tag,
//可理解为Gmail中的标签,对消息进行再归类,方便Consumer指定过滤条件在MQ服务器过滤。

"TagA",
//Message Body
//任何二进制形式的数据,MQ不做任何干预,需要Producer与Consumer协商好一致的序列化和反序列化方式。

("Hello MQ").getBytes()
);
// 设置代表消息的业务关键属性,请尽可能全局唯一。

// 以方便您在无法正常收到消息情况下,可通过MQ Console查询消息并补发。

// 注意:不设置也不会影响消息正常收发。

msg.setKey("ORDERID_100");
3.MQTT收发消息示例代码
您可以按以下说明设置相应参数并测试MQTT消息接收功能:
//点对点模型,设置目标clientid
msg.putUserProperties("mqttSecondTopic", "/p2p/"+properties.getProperty(PropertyKeyConst.ConsumerId));//发送消息,只要不抛异常就是成功。

SendResult sendResult = producer.send(msg);
System.out.println(sendResult);
//发布订阅模型,设置多级topic。

msg.putUserProperties("mqttSecondTopic", "/notice/");
sendResult = producer.send(msg);
System.out.println(sendResult);
// 在应用退出前,销毁Producer对象。

// 注意:如果不销毁也没有问题。

producer.shutdown();
}
}
package com.aliyun.openservice.ons.mqtt.demo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import com.aliyun.openservice.ons.mqtt.tool.MacSignature;
public class MqttDemo {
public static void main(String[] args) throws IOException {
String broker = null;
String acessKey = null;
String secretKey = null;
String clientId = null;
Properties properties = new Properties();
properties.load(MqttDemo.class.getClassLoader().getResourceAsStream("user.properties"));
broker = properties.getProperty("broker");
acessKey = properties.getProperty("AccessKey");
secretKey = properties.getProperty("SecretKey");
final String topic = properties.getProperty("Topic");
//如果该设备需要接收点对点的推送,那么需要订阅二级topic,topic/p2p/,但凡以topic/p2p/为前缀的,都认为是点对点推送。

final String p2ptopic = topic+"/p2p/";
//同时订阅两个topic,一个是基于标准mqtt协议的发布订阅模式,一个是扩展的点对点推送模式。

final String[] topicFilters=new String[]{topic+"/notice/",p2ptopic};
clientId = properties.getProperty("ConsumerId");
String sign;
MemoryPersistence persistence = new MemoryPersistence();
try {
final MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
final MqttConnectOptions connOpts = new MqttConnectOptions();
System.out.println("Connecting to broker: " + broker);
sign = MacSignature.macSignature(clientId.split("@@@")[0], secretKey);
connOpts.setUserName(acessKey);
connOpts.setServerURIs(new String[] { broker });
connOpts.setPassword(sign.toCharArray());
connOpts.setCleanSession(false);
connOpts.setKeepAliveInterval(100);
sampleClient.setCallback(new MqttCallback() {
public void connectionLost(Throwable throwable) {
while (true) {
try {
System.out.println("connectionLost");
throwable.printStackTrace();
Thread.sleep(1000L);
sampleClient.connect(connOpts);
System.out.println("reconnect success");
sampleClient.subscribe(topicFilters);
System.out.println("subscribe....success");
break;
} catch (MqttSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MqttException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if (e.getReasonCode()==MqttException.REASON_CODE_CLIENT_CONNECTED) {
break;
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception { System.out.println("messageArrived:" + topic + "------" + new String(mqttMessage.getPayload())); }
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println("deliveryComplete:" + iMqttDeliveryToken.getMessageId());
}
});
sampleClient.connect(connOpts);
sampleClient.subscribe(topicFilters);
System.out.println("subscribe....success");
Thread.sleep(15000L);
for (int i = 0; i < 1; i++) {
String scontent = new Date()+"MQTT Test body" + i;
final MqttMessage message = new MqttMessage(scontent.getBytes());
message.setQos(1);
System.out.println(i+" pushed at "+new Date()+" "+ scontent);
//消息发送到某个主题topic,所有订阅这个topic的设备都能收到这个消息。

遵循mqtt的发布订阅规范,topic也可以是多级topic。

//除了点对点topic/p2p/这个前缀的,作为点对点发送的特殊topic,不遵循发布订阅模式。

sampleClient.publish(topic+"/notice/", message);
//发送给指定设备,格式为topic/p2p/targetClientId, targetClientId的格式详见user.properties文件。

sampleClient.publish(p2ptopic+properties.getProperty("ConsumerId"), message);
} catch (Exception e) {
e.printStackTrace();
}
}
Thread.sleep(Integer.MAX_VALUE);
} catch (Exception me) {
me.printStackTrace();
}
}
}
4.MQTT工具方法
如下代码是MQTT收发消息示例中所用的工具方法:
import mons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MacSignature {
/**
* @param text 要签名的文本
* @param secretKey 阿里云MQ secretKey
* @return 加密后的字符串
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
*/
public static String macSignature(String text, String secretKey) throws InvalidKeyException, NoSuchAlgorithmException {
Charset charset = Charset.forName("UTF-8");
String algorithm = "HmacSHA1";
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(secretKey.getBytes(charset), algorithm));
byte[] bytes = mac.doFinal(text.getBytes(charset));
return new String(Base64.encodeBase64(bytes), charset);
/**
* 发送方签名方法
*
* @param clientId Mqtt ClientId
* @param secretKey 阿里云MQ secretKey
* @return 加密后的字符串
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static String publishSignature(String clientId, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
return macSignature(clientId, secretKey);
}
/**
* 订阅方签名方法
*
* @param topics 要订阅的Topic集合
* @param clientId Mqtt ClientId
* @param secretKey 阿里云MQ secretKey
* @return 加密后的字符串
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static String subSignature(List<String> topics, String clientId, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
Collections.sort(topics); //以字典顺序排序
String topicText = "";
for (String topic : topics) {
topicText += topic + "\n";
}
String text = topicText + clientId;
return macSignature(text, secretKey);
}
/**
* 订阅方签名方法
*
* @param topic 要订阅的Topic
* @param clientId Mqtt ClientId
* @param secretKey 阿里云MQ secretKey
* @return 加密后的字符串
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static String subSignature(String topic, String clientId, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
List<String> topics = new ArrayList<String>();
topics.add(topic);
return subSignature(topics, clientId, secretKey);
}
}。

相关文档
最新文档