来自一位大手子@Eragonl,大家可以在csdn找到他
打开VisualStdio Installer后点击上方的单个组件后向下寻找到 .NET Framework的SDK和目标包,确认好至少安装了一个版本的SDK和目标包(我这里使用的是4.6.1的版本)
创建完成以后,现在我们来下载MQTT库的4.3.0版本。
首先我们需要在VS中创建两个C#窗体应用。创建完成以后,点开VS上方的“工具”,找到NuGet 包管理器,选择“程序包管理器控制台”,等待初始化结束以后在下方的PM>的后面输入“Install-Package M2Mqtt -Version 4.3.0”后按下回车,等待安装完成。
然后我们需要安装阿里云上物联网平台的SDK。进入 https://developer.aliyun.com/tools/sdk?spm=5176.11122631.962077.11.17e83801jxoNww#/dotnet ,下载 SDK核心库 以及 阿里云物联网平台 。
以及
下载后解压得到dll文件。在项目中右击右方“解决方案资源管理器”中的引用,点击添加引用后选择浏览,将刚刚下载的两个dll文件导入,这样就完成了开始项目前的准备。(也可以直接拖进引用这里)
在此之前,我们需要先注册一个阿里云上的账号,这个很简单,只需要百度“阿里云平台”,然后注册一个阿里云平台的账号即可,在此不做演示。然后进入链接 https://iot.console.aliyun.com/product?spm=a2c4g.11186623.2.16.18ce4c07ESOaSj 进行用户登录,将会出现如下所示的登录页面,提示输入注入用户名以及密码即可:
点击页面左边的“设备管理”->“产品”,在产品页面的右边有“创建产品”按钮:
点击该按钮之后,出现下面的“新建产品”页面:
因为我们的连接方式是WiFi,所以就不需要再选择接入网关了,故选择的是否。以及ID2认证的话,除非需要很高的安全性,不然一般情况下也是选择否。
在“产品列表”中打开具体的产品后,将会显示产品信息页面,其中有产品的型号(ProductKey)和产品密钥(ProductSecret),将数据保存在本地txt文档中,之后的程序中会用到这两个字符串。
创建产品完成以后点击“前往管理”进行设备的建立
点击“添加设备”,我们开始建立数据发出端的程序。
跳出如图的界面后自行填入DeviceName和备注名称,其中备注名称需要保存到txt文件中,之后的编程中需要使用。
点击确定后会跳出如图界面,将三个数据进行保存,之后的编程中也会用到
复制完成以后就会在设备列表中创建出一个未被激活的设备出来,这个设备我称之为A,我这里的名字为lalala,之后测试的时候设备A的名字会变成computer。
我们现在对设备A进行开发,我们现在要做的是用本地的C#代码连接设备A后将数据发送到云上,然后云再将数据返回来,由本地的C#进行接收。我们先写本地的C#程序:首先,窗体界面的建立,我们需要在VS上进行窗体的建立。点击左侧的工具箱,找到textBox,label还有button,将他们放置在窗体上。然后修改右下角的Text以及字体的大小和字种(不改其实也没问题)。如下图所示:
然后双击传输数据以后,进入编程界面,将下列代码复制进去:
(我这里的“传输数据”为button1;文字框为testBox1;“数据未上传”为label1;“数值为:”为label2;“注释为:…”为label3;“null”为label4)
(注:这里的代码不能直接全部复制进去!而是要根据自己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 WindowsFormsApp1
{
public partial class Form1 : Form
{
//阿里云的数据
static string ProductKey = "***";//来自自己的设备
static string DeviceName = "***";//来自自己的设备
static string DeviceSecret = "***";//来自自己的设备
static string RegionId = "cn-shanghai";
static string PubTopic = "/" + ProductKey + "/" + DeviceName + "/user/update";
static string SubTopic = "/" + ProductKey + "/" + DeviceName + "/user/get";
public Form1()
{
InitializeComponent();
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
button1.Text = "数据上传";
}
private void button1_Click(object sender, 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(DateTimeOffset.Now.ToUnixTimeMilliseconds());
string signmethod = "hmacmd5";
Dictionary dict = new Dictionary();
dict.Add("productKey", ProductKey);
dict.Add("deviceName", DeviceName);
dict.Add("clientId", clientId);
dict.Add("timestamp", t);
string mqttUserName = DeviceName + "&" + ProductKey;
string mqttPassword = IotSignUtils.sign(dict, DeviceSecret, signmethod);
string mqttClientId = clientId + "|securemode=3,signmethod=" + signmethod + ",timestamp=" + t + "|";
string targetServer = ProductKey + ".iot-as-mqtt." + RegionId + ".aliyuncs.com";
ConnectMqtt(targetServer, mqttClientId, mqttUserName, mqttPassword);
}
public void ConnectMqtt(string targetServer, string mqttClientId, string mqttUserName, string mqttPassword)
{
MqttClient client = new MqttClient(targetServer);
client.ProtocolVersion = MqttProtocolVersion.Version_3_1_1;
client.Connect(mqttClientId, mqttUserName, mqttPassword, false, 60);
client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
//发布消息
String content = textBox1.Text;
//将string类转换成byte[]
byte[] by1 = System.Text.Encoding.ASCII.GetBytes(content);
var id = client.Publish(PubTopic,by1);
//订阅消息
var id2 = client.Subscribe(new string[] { SubTopic }, new byte[] { 0 });
}
//client.Unsubscribe(topics);
public void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
// handle message received
string topic = e.Topic;
string message = Encoding.ASCII.GetString(e.Message);
//int length = message.Length;
label4.Text = message;
}
}
public class IotSignUtils//IoT平台接入password签名算法
{
public static string sign(Dictionary 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());
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();
}
}
}
然后我们登陆阿里云平台,进入物联网平台,点击左侧的规则引擎,会有一个数据流转列表,点击创建规则,规则描述可以不用填:
然后进入编辑页面,点击 编写SQL ,字段这一行输入 * ,表示直接透析,不需要SELECT。然后类型选择为 自定义 模式,选择我们的项目,我这里是test,然后选择我们的数据发出端,因为我们现在数据是从A到A,所以发出端就是设备A,我这里是computer,地址选择为user/update 就可以了。
点击确定后,我们再点击转发数据里面的添加操作,还是选择 自定义 ,选择我们的产品,我这里是 test ,然后这里还是选择设备A,因为我们数据的接收端还是设备A,在我这里也就是 computer,地址就是 user/get ,点击确定,这条将设备A得到的数据转给设备A的规则就完成了。然后回到规则引擎一开始的界面上,启动该规则引擎即可。
然后我们运行程序:
在文本框里输入我们要上传的值以后,点击“数据上传”,然后显示结果如下:
我们设备A的值经过阿里云后又被我们接受了回来,并显示在了原来null的位置上。我们还可以查看阿里云上的日志服务来看到数据的传递:
进入日志服务,我们就可以看到如图的界面,设备行为分析包含了上线,数据的上传,数据的发布等行为。我们由本地设备A传输给云的数据在上行消息分析里可以查看,由云传输给设备A的数据可以在下行消息分析里面查看。
由此单设备的与云传输数据就完成了。
在第二个任务的基础上,我们用同样的方法去在云上创建一个设备,我们称之为设备C,我这里是computer2。
我们测试的时候,设备A先是一个数据的发出端,设备C是数据的接收端;然后我们再让设备C作为数据的发出端,设备A作为数据的接收端,进行一个数据的双向传递。
首先我们先在阿里云上再创建一个设备出来(在同一个产品下),按照之前创建的方式即可。
然后我们再创建一个C#项目,也可以直接用之前写的设备A的代码复制出来就行,窗体改不改其实都可以。将里面对应好了的namespace以及DeviceName之类的string类进行修改,修改成设备C的参数即可。
然后我们需要去对阿里云上的规则引擎进行修改和增加。
我们先点开之前在任务2里创造好了的那条规则,将转发数据的地点进行修改:
将数据目的地的名字改为设备C的名字即可其他的都不需要进行修改。
修改完后,现在的这一条规则就是将数据由设备A转到设备C的一条规则。现在我们同样的,因为是双向通信,所以我们需要再建立一条由设备C到设备A的规则,与之前的那条规则一样,唯一有变动的就是这次是由computer2给computer,所以要把名字对调(原先是computer的选computer2,原先为computer2的选择computer),其他的都不用改变。
然后我们运行两个程序:(我这里设备C的界面改了下,不改也没什么问题)
数据由A->C:
数据由C->A
数值的显示有时可能会显示不出来,原因是操作速度过慢导致账号已下线。最快的解决办法是重新启动两个程序后快速操作上述操作。