提交 1fe5a378a3f9c8563ab8a486ff1c7b7e1dd542e9

作者 mq_online_test
1 个父辈 0af5a89f

init mqtt demo

1   -# lmq-demo
2   -Demo for LMQ
  1 +# 微消息队列 MQTT 示例说明
  2 +本代码提供阿里云微消息队列 MQTT 的运行示例,根据开发语言进行第一级分类,根据功能和场景进行二级分类。
  3 +由于部分语言的示例代码更新节奏不一,所以部分场景的示例会有缺失。后续会持续更新。因为 MQTT 是一个标准协议,因此所有开发语言的功能都是一致的。
  4 +
  5 +**注意:示例代码仅提供一个简单的方法和运行参考,其中的参数都已经脱敏,实际业务使用时需要替换成实际申请的资源。**
  6 +
  7 +## SDK 依赖安装
  8 +微消息队列 MQTT 支持标准的 MQTT 3.1.1 协议,理论上能够适配所有的 MQTT 客户端,因此阿里云官方并不提供 SDK 目前。
  9 +接入时可以选择以下推荐的第三方 SDK。不排除部分客户端存在细节上的兼容性问题。针对 MQTT 用户常用的平台,推荐对应的三方包如下:
  10 +
  11 +| 开发语言和平台 | 推荐的第三方 SDK | 相关链接 |
  12 +| ---------- | ----------------------- | ---------------------------------------- |
  13 +| Java | Eclipse Paho SDK | [http://www.eclipse.org/paho/clients/java/](http://www.eclipse.org/paho/clients/java/) |
  14 +| iOS | MQTT-Client-Framework | [https://github.com/ckrey/MQTT-Client-Framework](https://github.com/ckrey/MQTT-Client-Framework) |
  15 +| Android | Eclipse Paho SDK | [https://github.com/eclipse/paho.mqtt.android](https://github.com/eclipse/paho.mqtt.android) |
  16 +| JavaScript | Eclipse Paho JavaScript | [http://www.eclipse.org/paho/clients/js/](http://www.eclipse.org/paho/clients/js/) |
  17 +| Python | Eclipse Paho Python SDK | [https://pypi.python.org/pypi/paho-mqtt/](https://pypi.python.org/pypi/paho-mqtt/) |
  18 +|C| Eclipse Paho C SDK|https://eclipse.org/paho/clients/c/|
  19 +|C#| Eclipse Paho C# SDK|https://github.com/eclipse/paho.mqtt.m2mqtt|
  20 +|Go|Eclipse Paho Go SDK|https://github.com/eclipse/paho.mqtt.golang|
  21 +
  22 +其他语言的客户端 SDK 如 PHP 等暂时没有提供测试。如有需要可以访问 https://github.com/mqtt/mqtt.github.io/wiki/libraries 进行下载。
  23 +
  24 +本代码仓库仅提供示例方法和 Demo 片段,部分开发语言需要的工程框架和 IDE 配置不会提供,因此使用时请自行移植。
  25 +
  26 +
  27 +
... ...
  1 +using System;
  2 +using System.Collections.Generic;
  3 +using System.Linq;
  4 +using System.Net;
  5 +using System.Security.Cryptography;
  6 +using System.Text;
  7 +using System.Threading.Tasks;
  8 +using uPLibrary.Networking.M2Mqtt;
  9 +using uPLibrary.Networking.M2Mqtt.Messages;
  10 +namespace MQTTDemo
  11 +{
  12 + class MQTTDoNetDemo
  13 + {
  14 + static void Main(string[] args)
  15 + {
  16 + //实例 ID,购买后从控制台获取
  17 + String instanceId = "XXXXX";
  18 + //此处填写购买得到的 MQTT 接入点域名
  19 + String brokerUrl = "XXX.mqtt.aliyuncs.com";
  20 + //此处填写阿里云帐号 AccessKey
  21 + String accessKey = "XXXXXX";
  22 + //此处填写阿里云帐号 SecretKey
  23 + String secretKey = "XXXXXX";
  24 + //此处填写在 MQ 控制台创建的 Topic,作为 MQTT 的一级 Topic
  25 + String parentTopic = "XXXXX";
  26 + //此处填写客户端 ClientId,需要保证全局唯一,其中前缀部分即 GroupId 需要先在 MQ 控制台创建
  27 + String clientId = "GID_XXXX@@@XXXX";
  28 + MqttClient client = new MqttClient(brokerUrl);
  29 + client.MqttMsgPublishReceived += client_recvMsg;
  30 + client.MqttMsgPublished += client_publishSuccess;
  31 + client.ConnectionClosed += client_connectLose;
  32 + //username和 Password 签名模式下的设置方法,参考文档 https://help.aliyun.com/document_detail/48271.html?spm=a2c4g.11186623.6.553.217831c3BSFry7
  33 + String userName = "Signature|"+accessKey+"|"+instanceId;
  34 + String passWord = HMACSHA1(secretKey, clientId);
  35 + client.Connect(clientId, userName,passWord,true,60);
  36 + //订阅 Topic,支持多个 Topic,以及多级 Topic
  37 + string[] subTopicArray = { parentTopic+"/subDemo1", parentTopic+"/subDemo2/level3" };
  38 + byte[] qosLevels = { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE };
  39 + client.Subscribe(subTopicArray, qosLevels);
  40 + client.Publish(parentTopic + "/subDemo1", Encoding.UTF8.GetBytes("hello mqtt"),MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE,false);
  41 + //发送 P2P 消息,二级 topic 必须是 p2p,三级 topic 是接收客户端的 clientId
  42 + client.Publish(parentTopic + "/p2p/"+clientId, Encoding.UTF8.GetBytes("hello mqtt"), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, false);
  43 + System.Threading.Thread.Sleep(10000);
  44 + client.Disconnect();
  45 + }
  46 + static void client_recvMsg(object sender, MqttMsgPublishEventArgs e)
  47 + {
  48 + // access data bytes throug e.Message
  49 + Console.WriteLine("Recv Msg : Topic is "+e.Topic+" ,Body is "+Encoding.UTF8.GetString(e.Message));
  50 + }
  51 + static void client_publishSuccess(object sender, MqttMsgPublishedEventArgs e)
  52 + {
  53 + // access data bytes throug e.Message
  54 + Console.WriteLine("Publish Msg Success");
  55 + }
  56 + static void client_connectLose(object sender, EventArgs e)
  57 + {
  58 + // access data bytes throug e.Message
  59 + Console.WriteLine("Connect Lost,Try Reconnect");
  60 + }
  61 + public static string HMACSHA1(string key, string dataToSign)
  62 + {
  63 + Byte[] secretBytes = UTF8Encoding.UTF8.GetBytes(key);
  64 + HMACSHA1 hmac = new HMACSHA1(secretBytes);
  65 + Byte[] dataBytes = UTF8Encoding.UTF8.GetBytes(dataToSign);
  66 + Byte[] calcHash = hmac.ComputeHash(dataBytes);
  67 + String calcHashString = Convert.ToBase64String(calcHash);
  68 + return calcHashString;
  69 + }
  70 + }
  71 +}
0 72 \ No newline at end of file
... ...
不能预览此文件类型
不能预览此文件类型
... ... @@ -99,24 +99,39 @@ void connectionLost(void *context, char *cause) {
99 99 int main(int argc, char **argv) {
100 100 MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
101 101 MQTTAsync client;
  102 + //实例 ID,购买后从控制台获取
  103 + char * instanceId = "XXXX";
  104 + //测试收发消息的 Topic
102 105 topic = "XXXX";
103   - char *host = "XXX.mqtt.aliyuncs.com";
104   - char *groupId = "GID_XXXXX";
105   - char *deviceId = "XXXXX";
106   - char *accessKey = "XXXXX";
107   - char *secretKey = "XXXXX";
  106 + //接入点域名,从控制台获取
  107 + char *host = "XXXX.mqtt.aliyuncs.com";
  108 + //客户端使用的 GroupID,从控制台申请
  109 + char *groupId = "GID_XXXX";
  110 + //客户端 ClientID 的后缀,由业务自行指定,只需要保证全局唯一即可
  111 + char *deviceId = "XXXX";
  112 + //账号 AccessKey,从账号控制台获取
  113 + char *accessKey = "XXXX";
  114 + //账号 SecretKey,从账号控制台获取
  115 + char *secretKey = "XXXX";
  116 + //使用的协议端口,默认 tcp 协议使用1883
108 117 int port = 1883;
109 118 int qos = 0;
110 119 int cleanSession = 1;
111 120 int rc = 0;
112 121 char tempData[100];
113 122 int len = 0;
114   - HMAC(EVP_sha1(), secretKey, strlen(secretKey), groupId, strlen(groupId), tempData, &len);
  123 + //ClientID要求使用 GroupId 和 DeviceId 拼接而成,长度不得超过64个字符
  124 + char clientIdUrl[64];
  125 + sprintf(clientIdUrl, "%s@@@%s", groupId, deviceId);
  126 + //username和 Password 签名模式下的设置方法,参考文档 https://help.aliyun.com/document_detail/48271.html?spm=a2c4g.11186623.6.553.217831c3BSFry7
  127 + HMAC(EVP_sha1(), secretKey, strlen(secretKey), clientIdUrl, strlen(clientIdUrl), tempData, &len);
115 128 char resultData[100];
116 129 int passWordLen = EVP_EncodeBlock((unsigned char *) resultData, tempData, len);
117 130 resultData[passWordLen] = '\0';
118 131 printf("passWord is %s", resultData);
119   - userName = accessKey;
  132 + char userNameData[128];
  133 + sprintf(userNameData,"Signature|%s|%s", accessKey, instanceId);
  134 + userName = userNameData;
120 135 passWord = resultData;
121 136 //1.create client
122 137 MQTTAsync_createOptions create_opts = MQTTAsync_createOptions_initializer;
... ... @@ -124,8 +139,6 @@ int main(int argc, char **argv) {
124 139 create_opts.maxBufferedMessages = 10;
125 140 char url[100];
126 141 sprintf(url, "%s:%d", host, port);
127   - char clientIdUrl[64];
128   - sprintf(clientIdUrl, "%s@@@%s", groupId, deviceId);
129 142 rc = MQTTAsync_createWithOptions(&client, url, clientIdUrl, MQTTCLIENT_PERSISTENCE_NONE, NULL, &create_opts);
130 143 rc = MQTTAsync_setCallbacks(client, client, connectionLost, messageArrived, NULL);
131 144 //2.connect to server
... ...
MQTTChat @ 1b4eb1d6
  1 +Subproject commit 1b4eb1d6d9014806001cc15f0861bc0b62bb627c
... ...
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  3 + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml">
  5 +<head>
  6 + <title>Aliyun Mqtt Websockets</title>
  7 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8 + <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
  9 + <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js" type="text/javascript"></script>
  10 + <script type="text/javascript">
  11 + instanceId = 'XXXX';//实例 ID,购买后从控制台获取
  12 + host = 'XXXX.mqtt.aliyuncs.com';// 设置当前用户的接入点域名,接入点获取方法请参考接入准备章节文档,先在控制台创建实例
  13 + port = 80;//WebSocket 协议服务端口,如果是走 HTTPS,设置443端口
  14 + topic = 'XXXX';//需要操作的 Topic,第一级父级 topic 需要在控制台申请
  15 + useTLS = false;//是否走加密 HTTPS,如果走 HTTPS,设置为 true
  16 + accessKey = 'XXXXX';//账号的 AccessKey,在阿里云控制台查看
  17 + secretKey = 'XXXXX';//账号的的 SecretKey,在阿里云控制台查看
  18 + cleansession = true;
  19 + groupId = 'GID_XXXX';//MQTT GroupID,创建实例后从 MQTT 控制台创建
  20 + clientId = groupId + '@@@00001';//GroupId@@@DeviceId,由控制台创建的 Group ID 和自己指定的 Device ID 组合构成
  21 + var mqtt;
  22 + var reconnectTimeout = 2000;
  23 + var username = 'Signature|' + accessKey + '|' + instanceId;//username和 Password 签名模式下的设置方法,参考文档 https://help.aliyun.com/document_detail/48271.html?spm=a2c4g.11186623.6.553.217831c3BSFry7
  24 + var password = CryptoJS.HmacSHA1(clientId, secretKey).toString(CryptoJS.enc.Base64);
  25 +
  26 + function MQTTconnect() {
  27 + mqtt = new Paho.MQTT.Client(
  28 + host,//MQTT 域名
  29 + port,//WebSocket 端口,如果使用 HTTPS 加密则配置为443,否则配置80
  30 + clientId//客户端 ClientId
  31 + );
  32 + var options = {
  33 + timeout: 3,
  34 + onSuccess: onConnect,
  35 + mqttVersion: 4,
  36 + onFailure: function (message) {
  37 + setTimeout(MQTTconnect, reconnectTimeout);
  38 + }
  39 + };
  40 + mqtt.onConnectionLost = onConnectionLost;
  41 + mqtt.onMessageArrived = onMessageArrived;
  42 + if (username != null) {
  43 + options.userName = username;
  44 + options.password = password;
  45 + options.useSSL = useTLS;//如果使用 HTTPS 加密则配置为 true
  46 + }
  47 + mqtt.connect(options);
  48 + }
  49 +
  50 + function onConnect() {
  51 + // Connection succeeded; subscribe to our topic
  52 + mqtt.subscribe(topic, {qos: 0});
  53 + message = new Paho.MQTT.Message("Hello mqtt!!");//set body
  54 + message.destinationName = topic;// set topic
  55 + mqtt.send(message);
  56 + }
  57 +
  58 + function onConnectionLost(response) {
  59 + setTimeout(MQTTconnect, reconnectTimeout);
  60 + };
  61 +
  62 + function onMessageArrived(message) {
  63 + var topic = message.destinationName;
  64 + var payload = message.payloadString;
  65 + console.log("recv msg : " + topic + " " + payload);
  66 + };
  67 + MQTTconnect();
  68 + </script>
  69 +</head>
  70 +</html>
0 71 \ No newline at end of file
... ...
  1 +#!/usr/bin/env python
  2 +import hmac
  3 +import base64
  4 +from hashlib import sha1
  5 +import time
  6 +from paho.mqtt.client import MQTT_LOG_INFO, MQTT_LOG_NOTICE, MQTT_LOG_WARNING, MQTT_LOG_ERR, MQTT_LOG_DEBUG
  7 +from paho.mqtt import client as mqtt
  8 +# 实例 ID,购买后从产品控制台获取
  9 +instanceId ='XXXX'
  10 +
  11 +#账号AccessKey 从阿里云账号控制台获取
  12 +accessKey = 'XXXX'
  13 +
  14 +#账号secretKey 从阿里云账号控制台获取
  15 +secretKey = 'XXXX'
  16 +
  17 +#MQTT GroupID,创建实例后从 MQTT 控制台创建
  18 +groupId = 'GID_XXXX'
  19 +
  20 +#MQTT ClientID,由 GroupID 和后缀组成,需要保证全局唯一
  21 +client_id=groupId+'@@@'+'XXXXX'
  22 +
  23 +# Topic, 其中第一级父级 Topic 需要从控制台创建
  24 +topic = 'XXXXX'
  25 +
  26 +#MQTT 接入点域名,实例初始化之后从控制台获取
  27 +brokerUrl='XXXXXX.mqtt.aliyuncs.com'
  28 +
  29 +
  30 +def on_log(client, userdata, level, buf):
  31 + if level == MQTT_LOG_INFO:
  32 + head = 'INFO'
  33 + elif level == MQTT_LOG_NOTICE:
  34 + head = 'NOTICE'
  35 + elif level == MQTT_LOG_WARNING:
  36 + head = 'WARN'
  37 + elif level == MQTT_LOG_ERR:
  38 + head = 'ERR'
  39 + elif level == MQTT_LOG_DEBUG:
  40 + head = 'DEBUG'
  41 + else:
  42 + head = level
  43 + print('%s: %s' % (head, buf))
  44 +def on_connect(client, userdata, flags, rc):
  45 + print('Connected with result code ' + str(rc))
  46 +def on_message(client, userdata, msg):
  47 + print(msg.topic + ' ' + str(msg.payload))
  48 +def on_disconnect(client, userdata, rc):
  49 + if rc != 0:
  50 + print('Unexpected disconnection %s' % rc)
  51 +client = mqtt.Client(client_id, protocol=mqtt.MQTTv311, clean_session=True)
  52 +client.on_log = on_log
  53 +client.on_connect = on_connect
  54 +client.on_message = on_message
  55 +client.on_disconnect = on_disconnect
  56 +## username和 Password 签名模式下的设置方法,参考文档 https://help.aliyun.com/document_detail/48271.html?spm=a2c4g.11186623.6.553.217831c3BSFry7
  57 +userName ='Signature'+'|'+accessKey+'|'+instanceId;
  58 +password = base64.b64encode(hmac.new(secretKey.encode(), client_id.encode(), sha1).digest()).decode()
  59 +client.username_pw_set(userName, password)
  60 +client.connect(brokerUrl, 1883, 60)
  61 +client.subscribe(topic, 0)
  62 +for i in range(1, 11):
  63 + print(i)
  64 + rc = client.publish(topic, str(i), qos=0)
  65 + print ('rc: %s' % rc)
  66 + time.sleep(0.1)
  67 +client.loop_forever()
0 68 \ No newline at end of file
... ...