1、准备
下载MQTTNet库
2、界面设计
3、编程
public ClientForm()
{
InitializeComponent();
cbbClientQos.SelectedIndex = 0;
cbbClientRetain.SelectedIndex = 0;
this.btClientConnect.Tag = 0;
MonitorListBoxInitialize();
}
private Action<string> _updateMonitorAction;
/// <summary>
/// monitor列表显示控制
/// </summary>
private void MonitorListBoxInitialize()
{
_updateMonitorAction = new Action<string>((s) =>
{
this.lbxMonitor.Items.Add(s);
if (this.lbxMonitor.Items.Count > 100)
{
this.lbxMonitor.Items.RemoveAt(0);
}
var visibleItems = this.lbxMonitor.ClientRectangle.Height / this.lbxMonitor.ItemHeight;
this.lbxMonitor.TopIndex = this.lbxMonitor.Items.Count - visibleItems + 1;
});
}
#region EventProcess
private async void btClientConnect_Click(object sender, EventArgs e)
{
try
{
if (int.Parse(this.btClientConnect.Tag.ToString()) == 0)
{
await ClientStart();
}else if(int.Parse(this.btClientConnect.Tag.ToString()) == 1)
{
await ClientStop();
}
}catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void btClientPublish_Click(object sender, EventArgs e)
{
try
{
if(mqttClient==null || !mqttClient.IsConnected)
{
MessageBox.Show("请连接MQTT服务器", "消息", MessageBoxButtons.OK);
return;
}
string topic = this.rtbClentPublishTopic.Text;
if (topic.Trim() == "")
{
MessageBox.Show("Topic不能为空", "消息", MessageBoxButtons.OK);
}
string payload = this.rtbClientPublishPayLoad.Text;
ClientPublishMqttTopic(topic, payload);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void btClientSubscribe_Click(object sender, EventArgs e)
{
try
{
if (mqttClient == null || !mqttClient.IsConnected)
{
MessageBox.Show("请连接MQTT服务器", "消息", MessageBoxButtons.OK);
return;
}
string topic = this.tbClientSubscribe.Text;
if (topic.Trim() == "")
{
MessageBox.Show("Topic不能为空", "消息", MessageBoxButtons.OK);
}
ClientSubscribeTopic(topic);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
#endregion
#region MQTT Client
private MqttClient mqttClient = null;
private async Task ClientStart()
{
try
{
var ip = this.tbClientSetIp.Text;
var port = int.Parse(this.tbClientSetPort.Text.Trim());
var username = this.tbClientSetUsername.Text.Trim();
var password = this.tbClientSetPassword.Text.Trim();
var mqttFactory = new MqttFactory();
var options = new MqttClientOptions
{
ClientId = this.tbClientSetClientId.Text.Trim(),
ProtocolVersion=MQTTnet.Formatter.MqttProtocolVersion.V311,
ChannelOptions=new MqttClientTcpOptions
{
Server=ip,
Port=port
},
WillDelayInterval=10,
WillMessage=new MqttApplicationMessage()
{
Topic=$"LastWill/{this.tbClientSetClientId.Text.Trim()}",
Payload=Encoding.UTF8.GetBytes("Lost the connection"),
QualityOfServiceLevel=MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce
}
};
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
if (!string.IsNullOrEmpty(username))
{
options.Credentials = new MqttClientCredentials
{
Username = username,
Password = Encoding.UTF8.GetBytes(password)
};
}
options.CleanSession = true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
mqttClient = mqttFactory.CreateMqttClient() as MqttClient;
mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnMqttClientConnected);
mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnMqttClientDisConnected);
mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnSubscribeMessageReceived);
await mqttClient.ConnectAsync(options);
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端[{options.ClientId}]尝试连接");
}
catch(Exception ex)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端尝试连接出错:{ex.Message}");
}
}
private async Task ClientStop()
{
try
{
if (mqttClient == null) return;
await mqttClient.DisconnectAsync();
mqttClient = null;
}catch(Exception ex)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端尝试断开出错:{ex.Message}");
}
}
private async void ClientPublishMqttTopic(string topic,string payload)
{
try
{
var message = new MqttApplicationMessage()
{
Topic = topic,
Payload = Encoding.UTF8.GetBytes(payload),
QualityOfServiceLevel = (MqttQualityOfServiceLevel)this.cbbClientQos.SelectedIndex,
Retain = bool.Parse(this.cbbClientRetain.ToString())
};
await mqttClient.PublishAsync(message);
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端{mqttClient.Options.ClientId}发布主题{topic}成功");
}catch(Exception ex)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端{mqttClient.Options.ClientId}发布主题{topic}异常");
}
}
private async void ClientSubscribeTopic(string topic)
{
await mqttClient.SubscribeAsync(topic);
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端{mqttClient.Options.ClientId}订阅主题{topic}成功");
}
private async void ClientUnSubscribeTopic(string topic)
{
await mqttClient.UnsubscribeAsync(topic);
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端{mqttClient.Options.ClientId}取消主题{topic}成功");
}
private void OnSubscribeMessageReceived(MqttApplicationMessageReceivedEventArgs obj)
{
string Payload = Encoding.UTF8.GetString(obj.ApplicationMessage.Payload);
string Topic = obj.ApplicationMessage.Topic;
string QoS = obj.ApplicationMessage.QualityOfServiceLevel.ToString();
string Retained = obj.ApplicationMessage.Retain.ToString();
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端接收到消息Topic:{Topic},Qos:{QoS},Retained:{Retained}");
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端接收到消息Payload:{Payload}");
}
private void OnMqttClientDisConnected(MqttClientDisconnectedEventArgs obj)
{
this.btClientConnect.BeginInvoke(new Action<string, int, Color>((s, i, c) => {
this.btClientConnect.Text = s;
this.btClientConnect.Tag = i;
this.btClientConnect.BackColor = c;
}), "断开", 0, Color.LightGray);
}
private void OnMqttClientConnected(MqttClientConnectedEventArgs obj)
{
this.btClientConnect.BeginInvoke(new Action<string, int, Color>((s, i, c) => {
this.btClientConnect.Text = s;
this.btClientConnect.Tag = i;
this.btClientConnect.BackColor = c;
}),"连接",1,Color.LightGreen);
}
#endregion
4、运行效果