阿里云上通过MQTT协议,实现多设备的相互数据的稳定动态传输和使用(本地设备均采用c#窗体。。。

更新时间:2023-07-05 04:28:33 阅读: 评论:0

阿⾥云上通过MQTT协议,实现多设备的相互数据的稳定动态传输和使⽤(本地
设备均采⽤c#窗体。。。
窗体界⾯的建⽴
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
namespace iotxsdkmqttnet {
public class IotSignUtils {
public static string sign(Dictionary<string, string> param,
剖腹产后多久可以怀孕
string deviceSecret, string signMethod){
string[] sortedKey = param.Keys.ToArray();
Array.Sort(sortedKey);
StringBuilder builder =new StringBuilder();
foreach(var i in sortedKey){
builder.Append(i).Append(param[i]);
}
byte[] key = Encoding.UTF8.GetBytes(deviceSecret);
byte[] signContent = Encoding.UTF8.GetBytes(builder.ToString());
//这⾥根据signMethod对代码进⾏了⼀些动态调整,于是写了⼀个HMACMD5
var hmac =new HMACMD5(key);
byte[] hashBytes = hmac.ComputeHash(signContent);
StringBuilder signBuilder =new StringBuilder();
foreach(byte b in hashBytes)
signBuilder.AppendFormat("{0:x2}", b);
return signBuilder.ToString();
}
}
}
  这⾥我展⽰的代码是我当时还未放⼊C#窗体前,在外部项⽬中单独尝试的,所以没有窗体中的那些类,但是我们在最后的成品程序中,是需要将这段作为⼀个类放⼊到C#窗体程序中去的。由于VS中的C#窗体应⽤⾥要求public partial class Form1 : Form需要作为本地程序namespace⾥的第⼀个类,所以在拷贝代码的时候还请注意不要把代码放到public partial class Form1 : Form的前⾯。
  然后我们需要再写⼀个设备的激活程序,代码如下,其中有⼀部分需要⾃⼰更改,我已经加了注释上去。
using System;
裤子粘毛怎么解决
using System.Net;
using System.Collections.Generic;
using uPLibrary.Networking.M2Mqtt;//如果这⾥显⽰错误的话,请检查⼀下MQTT库是否已经安装好
using uPLibrary.Networking.M2Mqtt.Messages;//如果这⾥显⽰错误的话,请检查⼀下MQTT库是否已经安装好
using System.Text;
using System.Linq;
namespace iotMqttDemo {
class MainClass {
static string ProductKey ="";//这⾥输⼊你的产品的Productkey
static string DeviceName ="";//这⾥输⼊你的设备的DeviceName
static string DeviceSecret ="";//这⾥输⼊你的设备的DeviceSecret
static string RegionId ="cn-shanghai";//这⾥是根据你的ReginId填写的,可以根据⾃⼰的进⾏修改
老板心态心脏跳的快static string PubTopic ="/"+ ProductKey +"/"+ DeviceName +"/update";//发布端的topic
static string SubTopic ="/"+ ProductKey +"/"+ DeviceName +"/get";//订阅端的topic
public static void Main(string[] args)
{
{
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());//建⽴⼀个IPHostEntry host
string clientId = host.AddressList.FirstOrDefault(//设置clientID
ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString();
string t = Convert.ToString(DateTimeOfft.Now.ToUnixTimeMilliconds());
string signmethod ="hmacmd5";//采⽤hmacmd5
Dictionary<string, string> dict =new Dictionary<string, string>();
dict.Add("productKey", ProductKey);
dict.Add("deviceName", DeviceName);
dict.Add("clientId", clientId);
dict.Add("timestamp", t);
string mqttUrName = DeviceName +"&"+ ProductKey;
string mqttPassword = IotSignUtils.sign(dict, DeviceSecret, signmethod);
string mqttClientId = clientId +"|curemode=3,signmethod="+signmethod+",timestamp="+ t +"|";
string targetServer = ProductKey +".iot-as-mqtt."+ RegionId +".";
ConnectMqtt(targetServer, mqttClientId, mqttUrName, mqttPassword);//连接
}
static void ConnectMqtt(string targetServer, string mqttClientId, string mqttUrName, string mqttPassword){
MqttClient client =new MqttClient(targetServer);
client.ProtocolVersion = MqttProtocolVersion.Version_3_1_1;
client.Connect(mqttClientId, mqttUrName, mqttPassword,fal,60);
client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;//注册事件
//发布消息
演讲稿的格式图片String content ="1";//发送个数字1给阿⾥云,可以在⽇志记录⾥的上⾏数据中查看到这个1
var id = client.Publish(PubTopic, Encoding.ASCII.GetBytes(content));
//他函数的返回值为⽆符号的16位整数
//订阅消息
client.Subscribe(new string[]{ SubTopic },new byte[]{0});
//这⾥的0的意思是采⽤Qos三种⽅法:0,1,2中的0号⽅法,也就是只运⾏⼀次的意思
}
static void Client_MqttMsgPublishReceived(object nder, MqttMsgPublishEventArgs e)
{
//对获得的message的处理
string topic = e.Topic;
string message = Encoding.ASCII.GetString(e.Message);
}
}
}
  需要注意的是这⾥也只是⼀个算法,⽽不是⼀个完整的程序,单独运⾏这段代码会出现错误,我们要做的是把之前的代码合并并且结合到C#的窗体应⽤⾥⾯去。两个程序的头⽂件中有相同的地⽅,合并的时候记得删除这⼀部分,或者直接使⽤我下⾯的实例代码中的头⽂件,在C#窗体应⽤中的框架如下:
using System;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
using System.Windows.Forms;
using System.Security.Cryptography;
namespace jieshou
{
public partial class Form1 : Form
{
......
}
public class IotSignUtils//IoT平台接⼊password签名算法
{
.
.....
}
}
  在public class IotSignUtils中就只需要把之前的那段代码复制进来就⾏了,⽽对于设备端的具体操作,我们还需要对应C#的环境进⾏⼀定的加⼯和修改,不能直接复制进来使⽤。我这⾥的设备上线的时机是当我们在textBox输⼊完我们的值以后点击发送信息的时候,所以我们原先代码中的MainClass中的 public static void Main(string[] args) ⾥⾯的内容我们需要放在 private void button1_Click(object nder, EventArgs e) 这个事件中:
private void button1_Click(object nder, EventArgs e)
{
label1.Text ="数据已经上传!";
//开始连接阿⾥云
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
string clientId = host.AddressList.FirstOrDefault(
ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString();
string t = Convert.ToString(DateTimeOfft.Now.ToUnixTimeMilliconds());
string signmethod ="hmacmd5";
Dictionary<string, string> dict =new Dictionary<string, string>();
dict.Add("productKey", ProductKey);
dict.Add("deviceName", DeviceName);
dict.Add("clientId", clientId);
dict.Add("timestamp", t);
string mqttUrName = DeviceName +"&"+ ProductKey;
string mqttPassword = IotSignUtils.sign(dict, DeviceSecret, signmethod);
string mqttClientId = clientId +"|curemode=3,signmethod="+ signmethod +",timestamp="+ t +"|";
string targetServer = ProductKey +".iot-as-mqtt."+ RegionId +".";
ConnectMqtt(targetServer, mqttClientId, mqttUrName, mqttPassword);
}
  然后 MainClass 与 public static void Main(string[] args) 之间的静态变量我们需要放在 public partial class Form1 : Form 与public Form1() 之间,并且这⾥⼀定要特别注意的是,这⾥有⼀个与上⾯的不同的地⽅:因为我们等会需要和阿⾥云进⾏数据的交流,所以这⾥的Topic⼀定要修改,在 static string PubTopic 和 static string SubTopic 这两⾏中的 DeviceName 的后⾯⼀定要加上 /ur ,不然等会就会出现9236错误,也就是权限的错误。 事例如下:
namespace jieshou
{
public partial class Form1 : Form
{龙液酸汤乌鱼府
//阿⾥云的数据
static string ProductKey ="";//输⼊⾃⼰的ProductKey
static string DeviceName ="";//输⼊⾃⼰的DeviceName
static string DeviceSecret ="";//输⼊⾃⼰的DeviceSecret
信守承诺static string RegionId ="cn-shanghai";
static string PubTopic ="/"+ ProductKey +"/"+ DeviceName +"/ur/update";
static string SubTopic ="/"+ ProductKey +"/"+ DeviceName +"/ur/get";
public Form1()
{
......
}
.
.....
}
  但是光修改这么多还是远远不够的,因为就⽬前来说,我们还没有做将数据显⽰到C#窗体上的代码的修改,要想实现C#窗体显⽰的话,我们还需要修改 static void ConnectMqtt 函数以及 static void Client_MqttMsgPublishReceived 函数。
  我们先修改ConnectMqtt 函数:(函数类型改为 public void)
public void ConnectMqtt(string targetServer, string mqttClientId, string mqttUrName, string mqttPassword)
{
MqttClient client =new MqttClient(targetServer);
client.ProtocolVersion = MqttProtocolVersion.Version_3_1_1;
client.Connect(mqttClientId, mqttUrName, mqttPassword,fal,60);
client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
//订阅消息
client.Subscribe(new string[]{ SubTopic },new byte[]{0});
//发布消息,发布的消息为我们在textBox1上的Text
String content = textBox1.Text;
//他上传的数据需要时byte[],所以我们先需要将string类转换成byte[]
byte[] by1 = System.Text.Encoding.ASCII.GetBytes(content);
var id = client.Publish(PubTopic, by1);
}
  然后我们再修改Client_MqttMsgPublishReceived 函数:(函数类型改为 public void)
public void Client_MqttMsgPublishReceived(object nder, MqttMsgPublishEventArgs e)
{
//对获得的message的处理
string topic = e.Topic;
string message = Encoding.ASCII.GetString(e.Message);//从被订阅端获取消息
int length = message.Length;//我们先得到这条message的长度,
//因为是string所以调⽤他的length函数就可以了
label3.Text = message.Substring(0,length);//label3原先是null,
//后来就会变成message的内容,从头开始读,长度就是length
}
  有的⼈可能会在label3.Text这⾥会报错,原因是在于初始化的问题,需要在 public Form1() 中添加⼀⾏代码,加⼊后错误就解决了:
public Form1()
{
InitializeComponent();
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls =fal;
//加⼊这⾏代码
喊麦词顺口溜}
  做到这⼀步的时候,我们在设备上的开发就已经完成了,现在我们可以运⾏⼀下这个代码,然后在textBox上输⼊数字以后点击button1,然后就开始传输数据了:
程序运⾏前:设备处于离线状态
程序运⾏后:设备处于在线状态
数据的⽇志服务为:
由本地设备上传给阿⾥云的数据存放在上⾏消息分析中:

本文发布于:2023-07-05 04:28:33,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1079227.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:需要   代码   设备   数据   错误   消息   时候
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图