设备端快速接入(MQTT)
1.一个运行Linux系统的设备(或者虚拟机),本人使用raspbian系统的树莓派B+;
2.创建好产品和设备。前面的实践中已经创建了很多产品和设备,选一个设备使用即可。
3.下载解压相应C版Linux下的SDK
Linux下解压zip压缩包命令
unzip xxx.zip
4.修改样例程序中的产品、设备参数。
cd iotx-sdk-c/
vim sample/mqtt/mqtt.c
//进入编辑模式(按下i键)
//根据你的产品设备信息修改以下参数
#define PRODUCT_KEY "<你的产品key>"
#define DEVICE_NAME "<你的设备名>"
#define DEVICE_ID "<你的设备ID>"
#define DEVICE_SECRET "<你的设备秘钥>"
//修改完后保存退出。Esc,然后输入 :wq ,回车确认。
5.编译SDK
//在当前顶层目录下(iotx-sdk-c文件夹里)
make clean
make
//编译成功后,在相应目录生成可执行程序。
高亮的mqtt就是可执行文件。
在执行程序前,设备从未启动过,状态为未激活。
6.执行样例程序
//在顶层目录下时
./sample/mqtt/mqtt
demo就开始跑了,只要前面参数填写正确,设备认证就会通过,然后就是周期性发布消息。测试设备处于在线状态。
在控制台的相应设备的Topic列表里面可以看到发布消息数量。
7.服务端获取MNS消息
官方链接
根据官方的案例调试可行,不赘述。有点不足就是Demo打印的消息内容不直观,修改见下文处理加密的消息
处理加密的消息
加密的payload不方便检查消息内容,所以对demo程序作了修改,解析并解码消息。
方法一。转化消息字符串为JSON对象
//创建消息体的对象类
import java.io.Serializable;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class MnsMessage implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String messagetype;
private String payload;
private String messageid;
private String topic;
private String devicename;
private String timestamp;
public String getMessagetype() {
return messagetype;
}
public void setMessagetype(String messagetype) {
this.messagetype = messagetype;
}
public String getPayload() {
return payload;
}
public void setPayload(String payload) {
this.payload = payload;
}
public String getMessageid() {
return messageid;
}
public void setMessageid(String messageid) {
this.messageid = messageid;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public String getDevicename() {
return devicename;
}
public void setDevicename(String devicename) {
this.devicename = devicename;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
引入相关依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.12version>
dependency>
测试Demo
public class MNSTest {
public static void main(String[] args) {
CloudAccount account = new CloudAccount(
"******",
"******",
"************");
MNSClient client = account.getMNSClient();
CloudQueue queue = client.getQueueRef("aliyun-iot-******"); //参数请输入IoT自动创建的队列名称
while (true) {
// 获取消息
Message popMsg = queue.popMessage(10); //长轮询等待时间为10秒
try {
if (popMsg != null) {
String messageBody = popMsg.getMessageBody();
//System.out.println("PopMessage Body: "+ messageBody); //获取原始消息
MnsMessage parse = JSON.parseObject(messageBody, MnsMessage.class);
System.out.println(parse.toString());
System.out.println(new String(Base64.decodeBase64(parse.getPayload()), "UTF-8"));
queue.deleteMessage(popMsg.getReceiptHandle()); //从队列中删除消息
} else {
System.out.println("Continuing");
}
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}
方法二。按字符串解析。并不实用,已废弃
public class MNSTest {
public static void main(String[] args) {
CloudAccount account = new CloudAccount(
"******",
"******",
"************");
MNSClient client = account.getMNSClient();
CloudQueue queue = client.getQueueRef("aliyun-iot-******"); //参数请输入IoT自动创建的队列名称,
while (true) {
// 获取消息
Message popMsg = queue.popMessage(10); //长轮询等待时间为10秒
if (popMsg != null) {
String messageBody = popMsg.getMessageBody();
System.out.println("PopMessage Body: "
+ messageBody); //获取原始消息
try {
System.out.println(getPayLoad(messageBody));//输出解码后的消息内容
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
queue.deleteMessage(popMsg.getReceiptHandle()); //从队列中删除消息
} else {
System.out.println("Continuing");
}
}
}
//解析获取消息内容,然后解码获取明文
private static String getPayLoad(String messageBody) throws UnsupportedEncodingException{
int start = messageBody.indexOf("\"payload\":\"");
int end = messageBody.indexOf("\",\"messageid");
int length = "\"payload\":\"".length();
return new String(Base64.decodeBase64(messageBody.substring(start+length, end)), "UTF-8");
}
}