网络读卡器介绍:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.4c70645epqZlzn&ft=t&id=626618714746
本示例使用了MQTTNet插件
C# MQTTNETServer 源码
using MQTTnet.Client.Receiving;
using MQTTnet.Server;
using MQTTnet;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MQTTnet.Protocol;
namespace MQTTNETServerForms
{
public partial class Form1 : Form
{
private MqttServerOptionsBuilder optionBuilder;
private IMqttServer server;//mqtt服务器对象
List<TopicItem> Topics = new List<TopicItem>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//创建服务器对象
server = new MqttFactory().CreateMqttServer();
server.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(new Action<MqttApplicationMessageReceivedEventArgs>(Server_ApplicationMessageReceived));//绑定消息接收事件
server.ClientConnectedHandler = new MqttServerClientConnectedHandlerDelegate(new Action<MqttServerClientConnectedEventArgs>(Server_ClientConnected));//绑定客户端连接事件
server.ClientDisconnectedHandler = new MqttServerClientDisconnectedHandlerDelegate(new Action<MqttServerClientDisconnectedEventArgs>(Server_ClientDisconnected));//绑定客户端断开事件
server.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(new Action<MqttServerClientSubscribedTopicEventArgs>(Server_ClientSubscribedTopic));//绑定客户端订阅主题事件
server.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(new Action<MqttServerClientUnsubscribedTopicEventArgs>(Server_ClientUnsubscribedTopic));//绑定客户端退订主题事件
server.StartedHandler = new MqttServerStartedHandlerDelegate(new Action<EventArgs>(Server_Started));//绑定服务端启动事件
server.StoppedHandler = new MqttServerStoppedHandlerDelegate(new Action<EventArgs>(Server_Stopped));//绑定服务端停止事件
}
/// 绑定消息接收事件
private void Server_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
{
string msg = e.ApplicationMessage.ConvertPayloadToString();
WriteLog(">>> 收到消息:" + msg + ",QoS =" + e.ApplicationMessage.QualityOfServiceLevel + ",客户端=" + e.ClientId + ",主题:" + e.ApplicationMessage.Topic);
}
/// 绑定客户端连接事件
private void Server_ClientConnected(MqttServerClientConnectedEventArgs e)
{
Task.Run(new Action(() =>
{
lbClients.BeginInvoke(new Action(() =>
{
lbClients.Items.Add(e.ClientId);
}));
}));
WriteLog(">>> 客户端" + e.ClientId + "连接");
}
/// 绑定客户端断开事件
private void Server_ClientDisconnected(MqttServerClientDisconnectedEventArgs e)
{
Task.Run(new Action(() =>
{
lbClients.BeginInvoke(new Action(() =>
{
lbClients.Items.Remove(e.ClientId);
}));
}));
WriteLog(">>> 客户端" + e.ClientId + "断开");
}
/// 绑定客户端订阅主题事件
private void Server_ClientSubscribedTopic(MqttServerClientSubscribedTopicEventArgs e)
{
Task.Run(new Action(() =>
{
var topic = Topics.FirstOrDefault(t => t.Topic == e.TopicFilter.Topic);
if (topic == null)
{
topic = new TopicItem { Topic = e.TopicFilter.Topic, Count = 0 };
Topics.Add(topic);
}
if (!topic.Clients.Exists(c => c == e.ClientId))
{
topic.Clients.Add(e.ClientId);
topic.Count++;
}
lvTopic.Invoke(new Action(() =>
{
this.lvTopic.Items.Clear();
}));
foreach (var item in this.Topics)
{
lvTopic.Invoke(new Action(() =>
{
this.lvTopic.Items.Add($"{item.Topic}:{item.Count}");
}));
}
}));
WriteLog(">>> 客户端" + e.ClientId + "订阅主题" + e.TopicFilter.Topic);
}
/// 绑定客户端退订主题事件
private void Server_ClientUnsubscribedTopic(MqttServerClientUnsubscribedTopicEventArgs e)
{
Task.Run(new Action(() =>
{
var topic = Topics.FirstOrDefault(t => t.Topic == e.TopicFilter);
if (topic != null)
{
topic.Count--;
topic.Clients.Remove(e.ClientId);
}
this.lvTopic.Items.Clear();
foreach (var item in this.Topics)
{
this.lvTopic.Items.Add($"{item.Topic}:{item.Count}");
}
}));
WriteLog(">>> 客户端" + e.ClientId + "退订主题" + e.TopicFilter);
}
/// 绑定服务端启动事件
private void Server_Started(EventArgs e)
{
WriteLog(">>> 服务端已启动!");
Invoke(new Action(() => {
this.button1.Text = "停止服务";
}));
}
/// 绑定服务端停止事件
private void Server_Stopped(EventArgs e)
{
WriteLog(">>> 服务端已停止!");
Invoke(new Action(() => {
this.button1.Text = "启动MQTT服务";
}));
}
/// 显示日志
public void WriteLog(string message)
{
if (txtMsg.InvokeRequired)
{
txtMsg.Invoke(new Action(() =>
{
txtMsg.Text = "";
txtMsg.Text = (message + "\r");
}));
}
else
{
txtMsg.Text = "";
txtMsg.Text = (message + "\r");
}
}
[Obsolete]
private async void button1_Click(object sender, EventArgs e)
{
if (button1.Text == "启动MQTT服务") /// 启动服务
{
optionBuilder = new MqttServerOptionsBuilder()
.WithDefaultEndpointBoundIPAddress(System.Net.IPAddress.Parse(this.txtIP.Text))
.WithDefaultEndpointPort(int.Parse(this.txtPort.Text))
.WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(5000))
.WithConnectionValidator(t =>
{
string un = "", pwd = "";
un = this.txtUname.Text;
pwd = this.txtUpwd.Text;
if (t.Username != un || t.Password != pwd)
{
t.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
}
else
{
t.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
}
});
var option = optionBuilder.Build();
await server.StartAsync(option);
}
else
{
if (server != null) //停止服务
{
server.StopAsync();
}
}
}
}
}
C# MQTTNETClient 源码
using MQTTnet.Client.Options;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MQTTnet;
using static System.Windows.Forms.Design.AxImporter;
using System.Net.Security;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Collections;
using System.Net.Sockets;
using System.Net;
namespace MQTTNETClientForms
{
public partial class Form1 : Form
{
private MqttFactory factory;
private IManagedMqttClient mqttClient;//客户端mqtt对象
private MqttClientOptionsBuilder mqttClientOptions;
private ManagedMqttClientOptionsBuilder options;
private bool connstate;
string info = "0";
string ResponseStr;
bool AutoResp = true;
public Form1()
{
InitializeComponent();
}
public static bool checkip(string ipstr) //判断IP是否合法
{
IPAddress ip;
if (IPAddress.TryParse(ipstr, out ip))
{ return true; }
else { return false; }
}
public static string getChinesecode(string inputstr) //获取中文编码,显示汉字、TTS中文语音都要转换编码
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
int strlen = inputstr.Length;
string hexcode = "";
for (int i = 0; i < strlen; i++)
{
string str = inputstr.Substring(i, 1);
byte[] Chinesecodearry = System.Text.Encoding.GetEncoding(936).GetBytes(str);
int codelen = (byte)Chinesecodearry.Length;
if (codelen == 1)
{
hexcode = hexcode + str;
}
else
{
hexcode = hexcode + "\\x" + Chinesecodearry[0].ToString("X2") + Chinesecodearry[1].ToString("X2");
}
}
return hexcode;
}
public static string getjsonval(string totalstr, string namestr) //解析JSON数据
{
string valustr = "";
totalstr = totalstr.Replace("{", "");
totalstr = totalstr.Replace("}", "");
totalstr = totalstr.Replace("\"", "");
string[] dataArray = totalstr.Split(new char[2] { ',', ',' });
if (dataArray.GetUpperBound(0) > 0)
{
for (int i = 0; i < dataArray.Length; i++)
{
string[] dataArray2 = dataArray[i].Split(new char[2] { ':', ':' });
if (dataArray2[0] == namestr)
{
valustr = dataArray2[1];
break;
}
}
}
return valustr;
}
private void Form1_Load(object sender, EventArgs e)
{
string computerName = System.Net.Dns.GetHostName();
txtId.Text = computerName;
comboBox1.SelectedIndex = 1;
comboBox2.SelectedIndex = 0;
comboBox_server.SelectedIndex = 0;
}
/// 显示日志--------------------------------------------------------------------------------------------------------
private void WriteLog(string message)
{
if (txtMsg.InvokeRequired)
{
txtMsg.Invoke(new Action(() =>
{
txtMsg.Text = (message);
listBox1.Items.Add(message);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}));
}
else
{
txtMsg.Text = (message);
listBox1.Items.Add(message);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}
}
/// 订阅----------------------------------------------------------------------------------------------------------------
[Obsolete]
private async void btnSub_Click(object sender, EventArgs e)
{
if (connstate == false)
{
WriteLog(">>> 请先与MQTT服务器建立连接!");
return;
}
if (string.IsNullOrWhiteSpace(this.txtTopic.Text))
{
WriteLog(">>> 请输入主题");
return;
}
//在 MQTT 中有三种 QoS 级别:
//At most once(0) 最多一次
//At least once(1) 至少一次
//Exactly once(2) 恰好一次
//await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(this.tbTopic.Text).WithAtMostOnceQoS().Build());//最多一次, QoS 级别0
await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(this.txtTopic.Text).WithAtLeastOnceQoS().Build());//恰好一次, QoS 级别1
WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 成功订阅");
}
/// 发布------------------------------------------------------------------------------------------------------------------------------
private async void button1_Click(object sender, EventArgs e)
{
if (!checkip(comboBox_server.Text))
{
MessageBox.Show("请输入正确的MQTT服务器IP。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (button1.Text == "连接到MQTT服务器")
{
connstate = false;
factory = new MqttFactory();
mqttClient = factory.CreateManagedMqttClient();//创建客户端对象
//绑定断开事件
mqttClient.UseDisconnectedHandler(async ee =>
{
WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 与服务器之间的连接断开了,正在尝试重新连接");
Invoke(new Action(() =>
{
this.button1.Text = "连接到MQTT服务器";
this.comboBox_server.Enabled = true;
}));
// 等待 5s 时间
await Task.Delay(TimeSpan.FromSeconds(5));
try
{
if (factory == null) { factory = new MqttFactory(); }//创建客户端对象
if (mqttClient == null) { mqttClient = factory.CreateManagedMqttClient(); }//创建客户端对象
mqttClient.UseConnectedHandler(tt =>
{
connstate = true;
WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 连接到服务成功");
Invoke(new Action(() =>
{
// 更新UI的代码
this.button1.Text = "断开与MQTT服务器的连续";
this.comboBox_server.Enabled = false;
this.btnSub.PerformClick();
}));
});
}
catch (Exception ex)
{
connstate = false;
WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + $" >>> 重新连接服务器失败:{ex}");
Invoke(new Action(() =>
{
this.button1.Text = "连接到MQTT服务器";
this.comboBox_server.Enabled = true;
}));
}
});
//绑定接收事件
mqttClient.UseApplicationMessageReceivedHandler(aa =>
{
try
{
string msg = aa.ApplicationMessage.ConvertPayloadToString();
WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 消息:" + msg + ",QoS =" + aa.ApplicationMessage.QualityOfServiceLevel + ",客户端=" + aa.ClientId + ",主题:" + aa.ApplicationMessage.Topic);
if (AutoResp) //选择接收到消息立即回应
{
info = getjsonval(msg, "info");
string jihao = getjsonval(msg, "jihao");
string cardtype = getjsonval(msg, "cardtype");
string card = getjsonval(msg, "card");
string dn = getjsonval(msg, "dn");
Invoke(new Action(() =>
{
this.button3.PerformClick();
}));
}
}
catch (Exception ex)
{
WriteLog($"+ 消息 = " + ex.Message);
}
});
//绑定连接事件
mqttClient.UseConnectedHandler(ee =>
{
connstate = true;
WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 连接到服务成功");
Invoke(new Action(() =>
{
this.button1.Text = "断开与MQTT服务器的连续";
this.comboBox_server.Enabled = false;
this.btnSub.PerformClick();
}));
});
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithClientId(this.txtId.Text)
.WithTcpServer(this.comboBox_server.Text, int.Parse(this.txtPort.Text))
.WithCredentials(this.txtName.Text, this.txtUpwd.Text);
var options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(mqttClientOptions.Build())
.Build();
//开启
await mqttClient.StartAsync(options);
}
else
{
if (mqttClient != null)
{
if (mqttClient.IsStarted)
{
await mqttClient.StopAsync();
}
mqttClient.Dispose();
connstate = false;
}
button1.Text = "连接到MQTT服务器";
comboBox_server.Enabled = true;
}
}
private void groupBox1_Enter(object sender, EventArgs e)
{
}
private async void button2_Click(object sender, EventArgs e)
{
if (connstate == false)
{
WriteLog(">>> 请先与MQTT服务器建立连接!");
return;
}
if (string.IsNullOrWhiteSpace(this.textBox1.Text))
{
WriteLog(">>> 请输入主题");
return;
}
var result = await mqttClient.PublishAsync(
this.textBox1.Text,
this.txtContent.Text,
MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);//恰好一次, QoS 级别1
WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + $" >>> 主题:{this.textBox1.Text},消息:{this.txtContent.Text},结果: {result.ReasonCode}");
}
private async void button3_Click(object sender, EventArgs e)
{
if (comboBox2.SelectedIndex == 0)
{
ResponseStr = "Response=1";
ResponseStr = ResponseStr + "," + info;
if (checkBox2.Checked)
{
ResponseStr = ResponseStr + "," + getChinesecode(disptext.Text.Trim());
ResponseStr = ResponseStr + "," + delaytime.Value.ToString();
}
else
{
ResponseStr = ResponseStr + ",";
ResponseStr = ResponseStr + ",";
}
if (checkBox4.Checked)
{
ResponseStr = ResponseStr + "," + comboBox1.SelectedIndex.ToString();
}
else
{
ResponseStr = ResponseStr + ",";
}
if (checkBox3.Checked)
{
ResponseStr = ResponseStr + "," + getChinesecode("[" + Volume.Value.ToString() + "]" + voicetext.Text.Trim());
}
else
{
ResponseStr = ResponseStr + ",";
}
if (checkBox5.Checked)
{
ResponseStr = ResponseStr + "," + switch1.Value.ToString();
}
else
{
ResponseStr = ResponseStr + ",";
}
if (checkBox6.Checked)
{
ResponseStr = ResponseStr + "," + switch2.Value.ToString();
}
else
{
ResponseStr = ResponseStr + ",";
}
}
else
{
ResponseStr = "{\"Response\":\"json\",\"infotype\":\"1\"";
ResponseStr = ResponseStr + ",\"info\":\"" + info + "\"";
if (checkBox2.Checked)
{
ResponseStr = ResponseStr + ",\"disp\":\"" + getChinesecode(disptext.Text.Trim()) + "\"";
ResponseStr = ResponseStr + ",\"dispdelay\":\"" + delaytime.Value.ToString() + "\"";
}
if (checkBox4.Checked)
{
ResponseStr = ResponseStr + ",\"beeptype\":\"" + comboBox1.SelectedIndex.ToString() + "\"";
}
if (checkBox3.Checked)
{
ResponseStr = ResponseStr + ",\"voicetype\":\"" + getChinesecode("[" + Volume.Value.ToString() + "]" + voicetext.Text.Trim()) + "\"";
}
if (checkBox5.Checked)
{
ResponseStr = ResponseStr + ",\"k1delay\":\"" + switch1.Value.ToString() + "\"";
}
if (checkBox6.Checked)
{
ResponseStr = ResponseStr + ",\"k2delay\":\"" + switch2.Value.ToString() + "\"";
}
}
var result = await mqttClient.PublishAsync(
this.txtTopik.Text,
this.ResponseStr,
MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);//恰好一次, QoS 级别1
WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + $" >>> 主题:{this.txtTopik.Text},消息:{this.ResponseStr},结果: {result.ReasonCode}");
}
private void checkBox1_MouseUp(object sender, MouseEventArgs e)
{
if (checkBox1.Checked) { AutoResp = true; } else { AutoResp = false; }
}
private void listBox1_MouseUp(object sender, MouseEventArgs e)
{
if (listBox1.SelectedIndex >= 0)
{
txtMsg.Text = listBox1.Text;
}
}
}
}