Added MQTT tester, added input service

This commit is contained in:
2020-11-08 18:51:19 +01:00
parent e1a596dae9
commit f102b89a21
16 changed files with 1956 additions and 17 deletions

394
MQTTnet.TestApp.WinForm/Form1.Designer.cs generated Normal file
View File

@ -0,0 +1,394 @@
namespace MQTTnet.TestApp.WinForm
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.TextBoxPort = new System.Windows.Forms.TextBox();
this.ButtonServerStart = new System.Windows.Forms.Button();
this.ButtonServerStop = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox();
this.label3 = new System.Windows.Forms.Label();
this.TextBoxTopicPublished = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.ButtonPublisherStop = new System.Windows.Forms.Button();
this.ButtonPublisherStart = new System.Windows.Forms.Button();
this.TextBoxPublish = new System.Windows.Forms.TextBox();
this.ButtonPublish = new System.Windows.Forms.Button();
this.ButtonSubscriberStop = new System.Windows.Forms.Button();
this.ButtonSubscriberStart = new System.Windows.Forms.Button();
this.TextBoxSubscriber = new System.Windows.Forms.TextBox();
this.ButtonGeneratePublishedMessage = new System.Windows.Forms.Button();
this.label6 = new System.Windows.Forms.Label();
this.TextBoxTopicSubscribed = new System.Windows.Forms.TextBox();
this.ButtonSubscribe = new System.Windows.Forms.Button();
this.label7 = new System.Windows.Forms.Label();
this.trackBar1 = new System.Windows.Forms.TrackBar();
this.ButtonAutoPublisherStop = new System.Windows.Forms.Button();
this.ButtonAutoPublisherStart = new System.Windows.Forms.Button();
this.label8 = new System.Windows.Forms.Label();
this.checkBox1 = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(119, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(32, 15);
this.label1.TabIndex = 0;
this.label1.Text = "Port:";
//
// TextBoxPort
//
this.TextBoxPort.Location = new System.Drawing.Point(172, 21);
this.TextBoxPort.Name = "TextBoxPort";
this.TextBoxPort.Size = new System.Drawing.Size(100, 23);
this.TextBoxPort.TabIndex = 1;
this.TextBoxPort.Text = "1883";
this.TextBoxPort.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
//
// ButtonServerStart
//
this.ButtonServerStart.Location = new System.Drawing.Point(433, 21);
this.ButtonServerStart.Name = "ButtonServerStart";
this.ButtonServerStart.Size = new System.Drawing.Size(75, 23);
this.ButtonServerStart.TabIndex = 2;
this.ButtonServerStart.Text = "Start";
this.ButtonServerStart.UseVisualStyleBackColor = true;
this.ButtonServerStart.Click += new System.EventHandler(this.ButtonServerStartClick);
//
// ButtonServerStop
//
this.ButtonServerStop.Location = new System.Drawing.Point(514, 21);
this.ButtonServerStop.Name = "ButtonServerStop";
this.ButtonServerStop.Size = new System.Drawing.Size(75, 23);
this.ButtonServerStop.TabIndex = 3;
this.ButtonServerStop.Text = "Stop";
this.ButtonServerStop.UseVisualStyleBackColor = true;
this.ButtonServerStop.Click += new System.EventHandler(this.ButtonServerStopClick);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(33, 25);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(39, 15);
this.label2.TabIndex = 4;
this.label2.Text = "Server";
//
// maskedTextBox1
//
this.maskedTextBox1.Location = new System.Drawing.Point(0, 0);
this.maskedTextBox1.Name = "maskedTextBox1";
this.maskedTextBox1.Size = new System.Drawing.Size(100, 23);
this.maskedTextBox1.TabIndex = 5;
this.maskedTextBox1.Text = "maskedTextBox1";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(33, 79);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(90, 15);
this.label3.TabIndex = 5;
this.label3.Text = "Topic Published";
//
// TextBoxTopicPublished
//
this.TextBoxTopicPublished.Location = new System.Drawing.Point(164, 76);
this.TextBoxTopicPublished.Name = "TextBoxTopicPublished";
this.TextBoxTopicPublished.Size = new System.Drawing.Size(425, 23);
this.TextBoxTopicPublished.TabIndex = 1;
this.TextBoxTopicPublished.Text = "devices/output";
this.TextBoxTopicPublished.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(33, 109);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(90, 15);
this.label4.TabIndex = 5;
this.label4.Text = "Client Publisher";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(33, 224);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(96, 15);
this.label5.TabIndex = 5;
this.label5.Text = "Client Subscriber";
//
// ButtonPublisherStop
//
this.ButtonPublisherStop.Location = new System.Drawing.Point(514, 105);
this.ButtonPublisherStop.Name = "ButtonPublisherStop";
this.ButtonPublisherStop.Size = new System.Drawing.Size(75, 23);
this.ButtonPublisherStop.TabIndex = 3;
this.ButtonPublisherStop.Text = "Stop";
this.ButtonPublisherStop.UseVisualStyleBackColor = true;
this.ButtonPublisherStop.Click += new System.EventHandler(this.ButtonPublisherStopClick);
//
// ButtonPublisherStart
//
this.ButtonPublisherStart.Location = new System.Drawing.Point(433, 105);
this.ButtonPublisherStart.Name = "ButtonPublisherStart";
this.ButtonPublisherStart.Size = new System.Drawing.Size(75, 23);
this.ButtonPublisherStart.TabIndex = 2;
this.ButtonPublisherStart.Text = "Start";
this.ButtonPublisherStart.UseVisualStyleBackColor = true;
this.ButtonPublisherStart.Click += new System.EventHandler(this.ButtonPublisherStartClick);
//
// TextBoxPublish
//
this.TextBoxPublish.Location = new System.Drawing.Point(33, 134);
this.TextBoxPublish.Name = "TextBoxPublish";
this.TextBoxPublish.Size = new System.Drawing.Size(394, 23);
this.TextBoxPublish.TabIndex = 1;
this.TextBoxPublish.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
//
// ButtonPublish
//
this.ButtonPublish.Location = new System.Drawing.Point(514, 134);
this.ButtonPublish.Name = "ButtonPublish";
this.ButtonPublish.Size = new System.Drawing.Size(75, 23);
this.ButtonPublish.TabIndex = 3;
this.ButtonPublish.Text = "Publish";
this.ButtonPublish.UseVisualStyleBackColor = true;
this.ButtonPublish.Click += new System.EventHandler(this.ButtonPublishClick);
//
// ButtonSubscriberStop
//
this.ButtonSubscriberStop.Location = new System.Drawing.Point(514, 220);
this.ButtonSubscriberStop.Name = "ButtonSubscriberStop";
this.ButtonSubscriberStop.Size = new System.Drawing.Size(75, 23);
this.ButtonSubscriberStop.TabIndex = 3;
this.ButtonSubscriberStop.Text = "Stop";
this.ButtonSubscriberStop.UseVisualStyleBackColor = true;
this.ButtonSubscriberStop.Click += new System.EventHandler(this.ButtonSubscriberStopClick);
//
// ButtonSubscriberStart
//
this.ButtonSubscriberStart.Location = new System.Drawing.Point(433, 220);
this.ButtonSubscriberStart.Name = "ButtonSubscriberStart";
this.ButtonSubscriberStart.Size = new System.Drawing.Size(75, 23);
this.ButtonSubscriberStart.TabIndex = 2;
this.ButtonSubscriberStart.Text = "Start";
this.ButtonSubscriberStart.UseVisualStyleBackColor = true;
this.ButtonSubscriberStart.Click += new System.EventHandler(this.ButtonSubscriberStartClick);
//
// TextBoxSubscriber
//
this.TextBoxSubscriber.Location = new System.Drawing.Point(33, 309);
this.TextBoxSubscriber.Multiline = true;
this.TextBoxSubscriber.Name = "TextBoxSubscriber";
this.TextBoxSubscriber.Size = new System.Drawing.Size(556, 182);
this.TextBoxSubscriber.TabIndex = 6;
//
// ButtonGeneratePublishedMessage
//
this.ButtonGeneratePublishedMessage.Location = new System.Drawing.Point(433, 133);
this.ButtonGeneratePublishedMessage.Name = "ButtonGeneratePublishedMessage";
this.ButtonGeneratePublishedMessage.Size = new System.Drawing.Size(75, 23);
this.ButtonGeneratePublishedMessage.TabIndex = 2;
this.ButtonGeneratePublishedMessage.Text = "Random";
this.ButtonGeneratePublishedMessage.UseVisualStyleBackColor = true;
this.ButtonGeneratePublishedMessage.Click += new System.EventHandler(this.ButtonGeneratePublishedMessageClick);
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(33, 252);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(96, 15);
this.label6.TabIndex = 5;
this.label6.Text = "Topic Subscribed";
//
// TextBoxTopicSubscribed
//
this.TextBoxTopicSubscribed.Location = new System.Drawing.Point(164, 249);
this.TextBoxTopicSubscribed.Name = "TextBoxTopicSubscribed";
this.TextBoxTopicSubscribed.Size = new System.Drawing.Size(344, 23);
this.TextBoxTopicSubscribed.TabIndex = 1;
this.TextBoxTopicSubscribed.Text = "devices/output";
this.TextBoxTopicSubscribed.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
//
// ButtonSubscribe
//
this.ButtonSubscribe.Location = new System.Drawing.Point(514, 248);
this.ButtonSubscribe.Name = "ButtonSubscribe";
this.ButtonSubscribe.Size = new System.Drawing.Size(75, 23);
this.ButtonSubscribe.TabIndex = 3;
this.ButtonSubscribe.Text = "Subscribe";
this.ButtonSubscribe.UseVisualStyleBackColor = true;
this.ButtonSubscribe.Click += new System.EventHandler(this.ButtonSubscribeClick);
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(33, 167);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(141, 15);
this.label7.TabIndex = 5;
this.label7.Text = "Auto (Random) Publisher";
//
// trackBar1
//
this.trackBar1.LargeChange = 500;
this.trackBar1.Location = new System.Drawing.Point(180, 162);
this.trackBar1.Maximum = 5050;
this.trackBar1.Minimum = 50;
this.trackBar1.Name = "trackBar1";
this.trackBar1.Size = new System.Drawing.Size(247, 45);
this.trackBar1.SmallChange = 100;
this.trackBar1.TabIndex = 7;
this.trackBar1.TickFrequency = 500;
this.trackBar1.Value = 550;
this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll);
//
// ButtonAutoPublisherStop
//
this.ButtonAutoPublisherStop.Location = new System.Drawing.Point(513, 162);
this.ButtonAutoPublisherStop.Name = "ButtonAutoPublisherStop";
this.ButtonAutoPublisherStop.Size = new System.Drawing.Size(75, 23);
this.ButtonAutoPublisherStop.TabIndex = 8;
this.ButtonAutoPublisherStop.Text = "Stop";
this.ButtonAutoPublisherStop.UseVisualStyleBackColor = true;
this.ButtonAutoPublisherStop.Click += new System.EventHandler(this.ButtonAutoPublisherStopClick);
//
// ButtonAutoPublisherStart
//
this.ButtonAutoPublisherStart.Location = new System.Drawing.Point(433, 162);
this.ButtonAutoPublisherStart.Name = "ButtonAutoPublisherStart";
this.ButtonAutoPublisherStart.Size = new System.Drawing.Size(75, 23);
this.ButtonAutoPublisherStart.TabIndex = 8;
this.ButtonAutoPublisherStart.Text = "Start";
this.ButtonAutoPublisherStart.UseVisualStyleBackColor = true;
this.ButtonAutoPublisherStart.Click += new System.EventHandler(this.ButtonAutoPublisherStartClick);
//
// label8
//
this.label8.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(180, 191);
this.label8.Name = "label8";
this.label8.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.label8.Size = new System.Drawing.Size(44, 15);
this.label8.TabIndex = 9;
this.label8.Text = "550 ms";
this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Checked = true;
this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBox1.Location = new System.Drawing.Point(433, 191);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(82, 19);
this.checkBox1.TabIndex = 10;
this.checkBox1.Text = "randomize";
this.checkBox1.UseVisualStyleBackColor = true;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(627, 530);
this.Controls.Add(this.checkBox1);
this.Controls.Add(this.label8);
this.Controls.Add(this.ButtonAutoPublisherStart);
this.Controls.Add(this.ButtonAutoPublisherStop);
this.Controls.Add(this.trackBar1);
this.Controls.Add(this.label7);
this.Controls.Add(this.TextBoxSubscriber);
this.Controls.Add(this.label5);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.ButtonServerStop);
this.Controls.Add(this.ButtonServerStart);
this.Controls.Add(this.TextBoxPort);
this.Controls.Add(this.label1);
this.Controls.Add(this.TextBoxTopicPublished);
this.Controls.Add(this.ButtonPublisherStop);
this.Controls.Add(this.ButtonPublisherStart);
this.Controls.Add(this.TextBoxPublish);
this.Controls.Add(this.ButtonPublish);
this.Controls.Add(this.ButtonSubscriberStop);
this.Controls.Add(this.ButtonSubscriberStart);
this.Controls.Add(this.ButtonGeneratePublishedMessage);
this.Controls.Add(this.label6);
this.Controls.Add(this.TextBoxTopicSubscribed);
this.Controls.Add(this.ButtonSubscribe);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "Form1";
this.Text = "MQTT Testing";
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox TextBoxPort;
private System.Windows.Forms.Button ButtonServerStart;
private System.Windows.Forms.Button ButtonServerStop;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.MaskedTextBox maskedTextBox1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Button ButtonPublisherStop;
private System.Windows.Forms.Button ButtonPublisherStart;
private System.Windows.Forms.TextBox TextBoxPublish;
private System.Windows.Forms.Button ButtonPublish;
private System.Windows.Forms.Button ButtonSubscriberStop;
private System.Windows.Forms.Button ButtonSubscriberStart;
private System.Windows.Forms.TextBox TextBoxSubscriber;
private System.Windows.Forms.Button ButtonGeneratePublishedMessage;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.TextBox TextBoxTopicPublished;
private System.Windows.Forms.Button ButtonSubscribe;
private System.Windows.Forms.TextBox TextBoxTopicSubscribed;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.TrackBar trackBar1;
private System.Windows.Forms.Button ButtonAutoPublisherStop;
private System.Windows.Forms.Button ButtonAutoPublisherStart;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.CheckBox checkBox1;
}
}

View File

@ -0,0 +1,476 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Form1.cs" company="Haemmer Electronics">
// Copyright (c) 2020 All rights reserved.
// </copyright>
// <summary>
// The main form.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace MQTTnet.TestApp.WinForm
{
using System;
using System.Text;
using System.Timers;
using System.Windows.Forms;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Formatter;
using MQTTnet.Protocol;
using MQTTnet.Server;
using Newtonsoft.Json;
using Timer = System.Timers.Timer;
/// <summary>
/// The main form.
/// </summary>
public partial class Form1 : Form
{
/// <summary>
/// The managed publisher client.
/// </summary>
private IManagedMqttClient managedMqttClientPublisher;
/// <summary>
/// The managed subscriber client.
/// </summary>
private IManagedMqttClient managedMqttClientSubscriber;
/// <summary>
/// The MQTT server.
/// </summary>
private IMqttServer mqttServer;
/// <summary>
/// The port.
/// </summary>
private string port = "1883";
private readonly Random random;
private readonly Timer randomPublisherTimer;
/// <summary>
/// Initializes a new instance of the <see cref="Form1"/> class.
/// </summary>
public Form1()
{
this.InitializeComponent();
var timer = new Timer
{
AutoReset = true, Enabled = true, Interval = 1000
};
timer.Elapsed += this.TimerElapsed;
random = new Random();
randomPublisherTimer = new Timer
{
AutoReset = true,
Enabled = false,
};
randomPublisherTimer.Elapsed += (_, __) => this.BeginInvoke((MethodInvoker)delegate
{
if (checkBox1.Checked)
ButtonGeneratePublishedMessageClick(ButtonGeneratePublishedMessage, EventArgs.Empty);
ButtonPublishClick(ButtonPublish, EventArgs.Empty);
});
}
/// <summary>
/// Handles the publisher connected event.
/// </summary>
/// <param name="x">The MQTT client connected event args.</param>
private void OnPublisherConnected(MqttClientConnectedEventArgs x)
{
var item = "Publisher Connected";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// Handles the publisher disconnected event.
/// </summary>
/// <param name="x">The MQTT client disconnected event args.</param>
private void OnPublisherDisconnected(MqttClientDisconnectedEventArgs x)
{
var item = "Publisher Disconnected";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// Handles the subscriber connected event.
/// </summary>
/// <param name="x">The MQTT client connected event args.</param>
private void OnSubscriberConnected(MqttClientConnectedEventArgs x)
{
var item = "Subscriber Connected";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// Handles the subscriber disconnected event.
/// </summary>
/// <param name="x">The MQTT client disconnected event args.</param>
private void OnSubscriberDisconnected(MqttClientDisconnectedEventArgs x)
{
var item = "Subscriber Disconnected";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// The method that handles the button click to generate a message.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private void ButtonGeneratePublishedMessageClick(object sender, EventArgs e)
{
var message = new
{
tag = Guid.NewGuid(),
probability = random.NextDouble(),
};
var json = JsonConvert.SerializeObject(message);
this.TextBoxPublish.Text = json;
}
/// <summary>
/// The method that handles the button click to publish a message.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonPublishClick(object sender, EventArgs e)
{
((Button)sender).Enabled = false;
try
{
var payload = Encoding.UTF8.GetBytes(this.TextBoxPublish.Text);
var message = new MqttApplicationMessageBuilder().WithTopic(this.TextBoxTopicPublished.Text.Trim()).WithPayload(payload).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce).WithRetainFlag().Build();
if (this.managedMqttClientPublisher != null)
{
await this.managedMqttClientPublisher.PublishAsync(message);
}
}
catch (Exception ex)
{
var item = ex.Message;
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
((Button)sender).Enabled = true;
}
/// <summary>
/// The method that handles the button click to start the publisher.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonPublisherStartClick(object sender, EventArgs e)
{
var mqttFactory = new MqttFactory();
var tlsOptions = new MqttClientTlsOptions
{
UseTls = false, IgnoreCertificateChainErrors = true, IgnoreCertificateRevocationErrors = true, AllowUntrustedCertificates = true
};
var options = new MqttClientOptions
{
ClientId = "ClientPublisher",
ProtocolVersion = MqttProtocolVersion.V311,
ChannelOptions = new MqttClientTcpOptions
{
Server = "localhost", Port = int.Parse(this.TextBoxPort.Text.Trim()), TlsOptions = tlsOptions
}
};
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
options.Credentials = new MqttClientCredentials
{
Username = "username", Password = Encoding.UTF8.GetBytes("password")
};
options.CleanSession = true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
this.managedMqttClientPublisher = mqttFactory.CreateManagedMqttClient();
this.managedMqttClientPublisher.UseApplicationMessageReceivedHandler(this.HandleReceivedApplicationMessage);
this.managedMqttClientPublisher.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnPublisherConnected);
this.managedMqttClientPublisher.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnPublisherDisconnected);
await this.managedMqttClientPublisher.StartAsync(
new ManagedMqttClientOptions
{
ClientOptions = options
});
}
/// <summary>
/// The method that handles the button click to stop the publisher.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonPublisherStopClick(object sender, EventArgs e)
{
if (this.managedMqttClientPublisher == null)
{
return;
}
await this.managedMqttClientPublisher.StopAsync();
this.managedMqttClientPublisher = null;
}
/// <summary>
/// The method that handles the button click to start the server.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonServerStartClick(object sender, EventArgs e)
{
if (this.mqttServer != null)
{
return;
}
var storage = new JsonServerStorage();
storage.Clear();
this.mqttServer = new MqttFactory().CreateMqttServer();
var options = new MqttServerOptions();
options.DefaultEndpointOptions.Port = int.Parse(this.TextBoxPort.Text);
options.Storage = storage;
options.EnablePersistentSessions = true;
options.ConnectionValidator = new MqttServerConnectionValidatorDelegate(
c =>
{
if (c.ClientId.Length < 10)
{
c.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
return;
}
if (c.Username != "username")
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
if (c.Password != "password")
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
c.ReasonCode = MqttConnectReasonCode.Success;
});
try
{
await this.mqttServer.StartAsync(options);
}
catch (Exception ex)
{
var item = ex.Message;
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
await this.mqttServer.StopAsync();
this.mqttServer = null;
}
}
/// <summary>
/// The method that handles the button click to stop the server.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonServerStopClick(object sender, EventArgs e)
{
if (this.mqttServer == null)
{
return;
}
await this.mqttServer.StopAsync();
this.mqttServer = null;
}
/// <summary>
/// The method that handles the button click to subscribe to a certain topic.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonSubscribeClick(object sender, EventArgs e)
{
var topicFilter = new MqttTopicFilter { Topic = this.TextBoxTopicSubscribed.Text.Trim() };
await this.managedMqttClientSubscriber.SubscribeAsync(topicFilter);
var item = "Topic " + this.TextBoxTopicSubscribed.Text.Trim() + " is subscribed";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// The method that handles the button click to start the subscriber.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonSubscriberStartClick(object sender, EventArgs e)
{
var mqttFactory = new MqttFactory();
var tlsOptions = new MqttClientTlsOptions
{
UseTls = false, IgnoreCertificateChainErrors = true, IgnoreCertificateRevocationErrors = true, AllowUntrustedCertificates = true
};
var options = new MqttClientOptions
{
ClientId = "ClientSubscriber",
ProtocolVersion = MqttProtocolVersion.V311,
ChannelOptions = new MqttClientTcpOptions
{
Server = "localhost", Port = int.Parse(this.TextBoxPort.Text.Trim()), TlsOptions = tlsOptions
}
};
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
options.Credentials = new MqttClientCredentials
{
Username = "username",
Password = Encoding.UTF8.GetBytes("password")
};
options.CleanSession = true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
this.managedMqttClientSubscriber = mqttFactory.CreateManagedMqttClient();
this.managedMqttClientSubscriber.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);
this.managedMqttClientSubscriber.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);
this.managedMqttClientSubscriber.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(this.OnSubscriberMessageReceived);
await this.managedMqttClientSubscriber.StartAsync(
new ManagedMqttClientOptions
{
ClientOptions = options
});
}
/// <summary>
/// The method that handles the button click to stop the subscriber.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private async void ButtonSubscriberStopClick(object sender, EventArgs e)
{
if (this.managedMqttClientSubscriber == null)
{
return;
}
await this.managedMqttClientSubscriber.StopAsync();
this.managedMqttClientSubscriber = null;
}
/// <summary>
/// Handles the received application message event.
/// </summary>
/// <param name="x">The MQTT application message received event args.</param>
private void HandleReceivedApplicationMessage(MqttApplicationMessageReceivedEventArgs x)
{
var item = $"Timestamp: {DateTime.Now:O} | Topic: {x.ApplicationMessage.Topic} | Payload: {x.ApplicationMessage.ConvertPayloadToString()} | QoS: {x.ApplicationMessage.QualityOfServiceLevel}";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// Handles the received subscriber message event.
/// </summary>
/// <param name="x">The MQTT application message received event args.</param>
private void OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs x)
{
var item = $"Timestamp: {DateTime.Now:O} | Topic: {x.ApplicationMessage.Topic} | Payload: {x.ApplicationMessage.ConvertPayloadToString()} | QoS: {x.ApplicationMessage.QualityOfServiceLevel}";
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
}
/// <summary>
/// The method that handles the text changes in the text box.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private void TextBoxPortTextChanged(object sender, EventArgs e)
{
// ReSharper disable once StyleCop.SA1126
if (int.TryParse(this.TextBoxPort.Text, out _))
{
this.port = this.TextBoxPort.Text.Trim();
}
else
{
this.TextBoxPort.Text = this.port;
this.TextBoxPort.SelectionStart = this.TextBoxPort.Text.Length;
this.TextBoxPort.SelectionLength = 0;
}
}
/// <summary>
/// The method that handles the timer events.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The event args.</param>
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
this.BeginInvoke(
(MethodInvoker)delegate
{
// Server
this.TextBoxPort.Enabled = this.mqttServer == null;
this.ButtonServerStart.Enabled = this.mqttServer == null;
this.ButtonServerStop.Enabled = this.mqttServer != null;
// Publisher
this.ButtonPublisherStart.Enabled = this.managedMqttClientPublisher == null;
this.ButtonPublisherStop.Enabled = this.managedMqttClientPublisher != null;
// Auto Publisher
this.ButtonAutoPublisherStart.Enabled = !this.randomPublisherTimer.Enabled;
this.ButtonAutoPublisherStop.Enabled = this.randomPublisherTimer.Enabled;
// Subscriber
this.ButtonSubscriberStart.Enabled = this.managedMqttClientSubscriber == null;
this.ButtonSubscriberStop.Enabled = this.managedMqttClientSubscriber != null;
});
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
this.label8.Text = $"{this.trackBar1.Value:N0} ms";
this.randomPublisherTimer.Interval = this.trackBar1.Value;
}
private void ButtonAutoPublisherStartClick(object sender, EventArgs e)
{
((Button)sender).Enabled = false;
this.randomPublisherTimer.Start();
((Button)sender).Enabled = true;
}
private void ButtonAutoPublisherStopClick(object sender, EventArgs e)
{
((Button)sender).Enabled = false;
this.randomPublisherTimer.Stop();
((Button)sender).Enabled = true;
}
}
}

View File

@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,83 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="JsonServerStorage.cs" company="Haemmer Electronics">
// Copyright (c) 2020 All rights reserved.
// </copyright>
// <summary>
// The JSON server storage.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace MQTTnet.TestApp.WinForm
{
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using MQTTnet.Server;
using Newtonsoft.Json;
/// <inheritdoc cref="IMqttServerStorage"/>
/// <summary>
/// The JSON server storage.
/// </summary>
/// <seealso cref="IMqttServerStorage"/>
public class JsonServerStorage : IMqttServerStorage
{
/// <summary>
/// The file name.
/// </summary>
private readonly string filename = Path.Combine(Directory.GetCurrentDirectory(), "Retained.json");
/// <summary>
/// Clears the file.
/// </summary>
public void Clear()
{
if (File.Exists(this.filename))
{
File.Delete(this.filename);
}
}
/// <inheritdoc cref="IMqttServerStorage"/>
/// <summary>
/// Loads the retained messages.
/// </summary>
/// <returns>A <see cref="IList{T}"/> of <see cref="MqttApplicationMessage"/>.</returns>
/// <seealso cref="IMqttServerStorage"/>
public async Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
{
await Task.CompletedTask;
if (!File.Exists(this.filename))
{
return new List<MqttApplicationMessage>();
}
try
{
var json = await File.ReadAllTextAsync(this.filename);
return JsonConvert.DeserializeObject<List<MqttApplicationMessage>>(json);
}
catch
{
return new List<MqttApplicationMessage>();
}
}
/// <inheritdoc cref="IMqttServerStorage"/>
/// <summary>
/// Saves the retained messages to a file.
/// </summary>
/// <param name="messages">The messages.</param>
/// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
/// <seealso cref="IMqttServerStorage"/>
public async Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
{
await Task.CompletedTask;
var json = JsonConvert.SerializeObject(messages);
await File.WriteAllTextAsync(this.filename, json);
}
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GitVersionTask" Version="5.3.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MQTTnet" Version="3.0.11" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="3.0.11" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,32 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Program.cs" company="Haemmer Electronics">
// Copyright (c) 2020 All rights reserved.
// </copyright>
// <summary>
// The main program.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace MQTTnet.TestApp.WinForm
{
using System;
using System.Windows.Forms;
/// <summary>
/// The main program.
/// </summary>
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}