1、准备
安装MQTTNet库
2、界面设计
3、程序
public ServerForm()
{
InitializeComponent();
//获取本机IP
GetHostIpList();
}
#region FormLoad
private Action<string> _updateMonitorAction;
/// <summary>
/// 窗体加载内容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ServerForm_Load(object sender, EventArgs e)
{
try
{
GetHostIpList();
this.tbMqttServerPort.Text = "8080";
this.tbUsername.Text = "username";
this.tbPassword.Text = "password";
this.btMqttServerStart.Tag = 0;
MonitorListBoxInitialize();
}catch(Exception ex)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, ex.Message);
}
}
/// <summary>
/// 获取本机IP
/// </summary>
private void GetHostIpList()
{
var Ips = Dns.GetHostAddressesAsync(Dns.GetHostName());
List<string> ipList = new List<string>();
foreach (var ip in Ips.Result)
{
switch (ip.AddressFamily)
{
case AddressFamily.InterNetwork:
if (!ipList.Contains(ip.ToString()))
{
ipList.Add(ip.ToString());
}
break;
default:
break;
}
}
if (ipList.Count > 0)
{
this.cbbMqttServerIp.DataSource = ipList;
this.cbbMqttServerIp.SelectedIndex = 0;
}
}
/// <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;
});
}
/// <summary>
/// monitor列表清空
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbxMonitor_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar=='c' || e.KeyChar == 'C')
{
if(DialogResult.Yes==MessageBox.Show("Clear the Monitor View?", "Info", MessageBoxButtons.YesNo))
{
this.lbxMonitor.Items.Clear();
}
}
}
#endregion
#region EventProcess
private SetModel setModel = new SetModel();
/// <summary>
/// 开启/停止MQTT服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btMqttServerStart_Click(object sender, EventArgs e)
{
setModel.Ip = this.cbbMqttServerIp.SelectedItem.ToString();
setModel.Port = Convert.ToInt32(this.tbMqttServerPort.Text);
setModel.Username = this.tbUsername.Text;
setModel.Password = this.tbPassword.Text;
try
{
if (int.Parse(this.btMqttServerStart.Tag.ToString()) == 0)
{
StartMqttServer();
}
else if (int.Parse(this.btMqttServerStart.Tag.ToString()) == 1)
{
StopMqttServer();
}
}catch(Exception ex)
{
Console.WriteLine($"开启关闭异常{ex.Message}");
}
}
private void btServerPublish_Click(object sender, EventArgs e)
{
try
{
string topic = this.tbServerPublishTopic.Text;
if (topic.Trim() == "")
{
MessageBox.Show("Topic不能为空", "消息", MessageBoxButtons.OK);
}
string payload = this.tbServerPublishPayload.Text;
MqttServerPublishTopic(topic, payload);
}
catch(Exception ex)
{
Console.WriteLine($"服务器发布异常{ex.Message}");
}
}
#endregion
#region MQTT Server
private const int SERVER_BACK_LOG = 5;
private MqttServer mqttServer = null;
/// <summary>
/// Mqtt服务器启动
/// </summary>
private async void StartMqttServer()
{
try
{
if (mqttServer == null)
{
var optionsBuilder = new MqttServerOptionsBuilder()
.WithDefaultEndpointBoundIPAddress(IPAddress.Parse(setModel.Ip))
.WithDefaultEndpointPort(setModel.Port)
.WithConnectionBacklog(SERVER_BACK_LOG)
.WithConnectionValidator(c =>
{
if (setModel.Username == null || setModel.Password == null || c.Username != setModel.Username || c.Password != setModel.Password)
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
c.ReasonCode = MqttConnectReasonCode.Success;
}).WithSubscriptionInterceptor(c =>
{
c.AcceptSubscription = true;
}).WithApplicationMessageInterceptor(c =>
{
c.AcceptPublish = true;
});
//MqttServerOptions options = optionsBuilder.Build() as MqttServerOptions;
mqttServer = new MqttFactory().CreateMqttServer() as MqttServer;
mqttServer.StartedHandler = new MqttServerStartedHandlerDelegate(OnMqttServerStarted);
mqttServer.StoppedHandler = new MqttServerStoppedHandlerDelegate(OnMqttServerStoped);
mqttServer.ClientConnectedHandler = new MqttServerClientConnectedHandlerDelegate(OnMqttServerClientConnected);
mqttServer.ClientDisconnectedHandler = new MqttServerClientDisconnectedHandlerDelegate(OnMqttServerClientDisconnected);
mqttServer.ClientSubscribedTopicHandler = new MqttServerClientSubscribedTopicHandlerDelegate(OnMqttServerClientSubscribedTopic);
mqttServer.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(OnMqttServerClientUnSubscribedTopic);
mqttServer.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnServerApplicationMessageReceived);
await mqttServer.StartAsync(optionsBuilder.Build());
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT服务器启动成功");
}
}catch(Exception ex)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT服务器启动失败:{ex.Message}");
}
}
/// <summary>
/// Mqtt服务器停止
/// </summary>
private async void StopMqttServer()
{
if (mqttServer == null) return;
try
{
await mqttServer?.StopAsync();
mqttServer = null;
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT服务器停止成功");
}
catch (Exception ex)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT服务器停止失败:{ex.Message}");
}
}
private async void MqttServerPublishTopic(string topic, string payload)
{
var message = new MqttApplicationMessage()
{
Topic = topic,
Payload = Encoding.UTF8.GetBytes(payload)
};
await mqttServer.PublishAsync(message);
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT服务器发布成功:{topic}");
}
private void OnServerApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs obj)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"客户端[{obj.ClientId}]>> 主题:{obj.ApplicationMessage.Topic} 负荷:{Encoding.UTF8.GetString(obj.ApplicationMessage.Payload)} Qos:{obj.ApplicationMessage.QualityOfServiceLevel} 保留:{obj.ApplicationMessage.Retain}");
}
private void OnMqttServerClientUnSubscribedTopic(MqttServerClientUnsubscribedTopicEventArgs obj)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT客户端{obj.ClientId}已取消订阅主题{obj.TopicFilter}");
}
private void OnMqttServerClientSubscribedTopic(MqttServerClientSubscribedTopicEventArgs obj)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT客户端{obj.ClientId}已成功订阅主题{obj.TopicFilter}");
}
private void OnMqttServerClientDisconnected(MqttServerClientDisconnectedEventArgs obj)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT客户端{obj.ClientId}已断开");
}
private void OnMqttServerClientConnected(MqttServerClientConnectedEventArgs obj)
{
this.lbxMonitor.BeginInvoke(_updateMonitorAction, $"MQTT客户端{obj.ClientId}已连接");
}
private void OnMqttServerStoped(EventArgs obj)
{
if (!mqttServer.IsStarted)
{
btMqttServerStart.BeginInvoke(new Action<string,int, Color>((t,g, c) =>
{
btMqttServerStart.Text = t;
btMqttServerStart.Tag = g;
btMqttServerStart.BackColor = c;
}), "Start",0, Color.LightGray);
}
}
private void OnMqttServerStarted(EventArgs obj)
{
if (mqttServer.IsStarted)
{
btMqttServerStart.BeginInvoke(new Action<string,int, Color>((t,g,c) =>
{
btMqttServerStart.Text = t;
btMqttServerStart.Tag = g;
btMqttServerStart.BackColor = c;
}),"Stop",1,Color.LightGreen);
}
}
#endregion
4、实现效果