/trunk/WingMan/Communication/MQTTServer.cs |
@@ -1,9 +1,11 @@ |
using System; |
using System.Collections.Generic; |
using System.IO; |
using System.Linq; |
using System.Net; |
using System.Text; |
using System.Threading.Tasks; |
using System.Windows.Forms; |
using MQTTnet; |
using MQTTnet.Server; |
|
@@ -11,8 +13,10 @@ |
{ |
public class MQTTServer |
{ |
private WingManForm WingManForm { get; set; } |
private IMqttServer Server { get; set; } |
public bool ServerRunning { get; set; } |
public string Nick { get; set; } |
|
public MQTTServer() |
{ |
@@ -19,22 +23,147 @@ |
Server = new MqttFactory().CreateMqttServer(); |
} |
|
public MQTTServer(WingManForm wingManForm) : this() |
{ |
WingManForm = wingManForm; |
} |
|
public async Task Stop() |
{ |
UnbindHandlers(); |
|
await Server.StopAsync().ConfigureAwait(false); |
|
ServerRunning = false; |
} |
|
public async Task Start(IPAddress ipAddress, int port) |
public async Task Start(IPAddress ipAddress, int port, string nick) |
{ |
Nick = nick; |
|
var optionsBuilder = new MqttServerOptionsBuilder() |
.WithDefaultEndpointBoundIPAddress(ipAddress) |
.WithSubscriptionInterceptor(MQTTSubscriptionIntercept) |
.WithDefaultEndpointPort(port); |
|
BindHandlers(); |
|
await Server.StartAsync(optionsBuilder.Build()).ConfigureAwait(false); |
|
ServerRunning = true; |
} |
|
private void MQTTSubscriptionIntercept(MqttSubscriptionInterceptorContext context) |
{ |
if (context.TopicFilter.Topic != "lobby" && |
context.TopicFilter.Topic != "exchange") |
{ |
context.AcceptSubscription = false; |
context.CloseConnection = true; |
return; |
} |
|
context.AcceptSubscription = true; |
context.CloseConnection = false; |
} |
|
private void ServerOnClientUnsubscribedTopic(object sender, MqttClientUnsubscribedTopicEventArgs e) |
{ |
LogActivity(Properties.Strings.Client_unsubscribed_from_topic, e.ClientId, e.TopicFilter); |
} |
|
private void ServerOnClientSubscribedTopic(object sender, MqttClientSubscribedTopicEventArgs e) |
{ |
LogActivity(Properties.Strings.Client_subscribed_to_topic, e.ClientId, e.TopicFilter.Topic); |
} |
|
private void ServerOnClientDisconnected(object sender, MqttClientDisconnectedEventArgs e) |
{ |
LogActivity(Properties.Strings.Client_disconnected, e.ClientId); |
} |
|
private void ServerOnClientConnected(object sender, MqttClientConnectedEventArgs e) |
{ |
LogActivity(Properties.Strings.Client_connected, e.ClientId); |
} |
|
private void ServerOnStopped(object sender, EventArgs e) |
{ |
LogActivity(Properties.Strings.Server_stopped); |
} |
|
private void ServerOnStarted(object sender, EventArgs e) |
{ |
LogActivity(Properties.Strings.Server_started); |
} |
|
private void BindHandlers() |
{ |
Server.Started += ServerOnStarted; |
Server.Stopped += ServerOnStopped; |
Server.ClientConnected += ServerOnClientConnected; |
Server.ClientDisconnected += ServerOnClientDisconnected; |
Server.ClientSubscribedTopic += ServerOnClientSubscribedTopic; |
Server.ClientUnsubscribedTopic += ServerOnClientUnsubscribedTopic; |
Server.ApplicationMessageReceived += ServerOnApplicationMessageReceived; |
} |
|
private void ServerOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e) |
{ |
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload)) |
{ |
memoryStream.Position = 0L; |
|
var lobbyMessage = (LobbyMessage)LobbyMessage.XmlSerializer.Deserialize(memoryStream); |
|
UpdateLobbyMessage(lobbyMessage.Nick, lobbyMessage.Message); |
} |
} |
|
private void UnbindHandlers() |
{ |
Server.Started -= ServerOnStarted; |
Server.Stopped -= ServerOnStopped; |
Server.ClientConnected -= ServerOnClientConnected; |
Server.ClientDisconnected -= ServerOnClientDisconnected; |
Server.ClientSubscribedTopic -= ServerOnClientSubscribedTopic; |
Server.ClientUnsubscribedTopic -= ServerOnClientUnsubscribedTopic; |
Server.ApplicationMessageReceived -= ServerOnApplicationMessageReceived; |
} |
|
private void UpdateLobbyMessage(string client, string message) |
{ |
WingManForm.LobbyTextBox.Invoke((MethodInvoker)delegate |
{ |
WingManForm.LobbyTextBox.AppendText($"{client} : {message}" + Environment.NewLine); |
}); |
} |
|
private void LogActivity(params string[] messages) |
{ |
WingManForm.ActivityTextBox.Invoke((MethodInvoker) delegate |
{ |
WingManForm.ActivityTextBox.Text = |
string.Join(" : ", messages) + Environment.NewLine + WingManForm.ActivityTextBox.Text; |
}); |
} |
|
public async Task BroadcastLobbyMessage(string text) |
{ |
using (var memoryStream = new MemoryStream()) |
{ |
LobbyMessage.XmlSerializer.Serialize(memoryStream, new LobbyMessage() |
{ |
Message = text, |
Nick = Nick |
}); |
|
memoryStream.Position = 0L; |
|
await Server.PublishAsync( |
new MqttApplicationMessage { Payload = memoryStream.ToArray(), Topic = "lobby" }); |
|
} |
} |
} |
} |
/trunk/WingMan/WingManForm.Designer.cs |
@@ -0,0 +1,480 @@ |
namespace WingMan |
{ |
partial class WingManForm |
{ |
/// <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.groupBox1 = new System.Windows.Forms.GroupBox(); |
this.comboBox1 = new System.Windows.Forms.ComboBox(); |
this.button2 = new System.Windows.Forms.Button(); |
this.button1 = new System.Windows.Forms.Button(); |
this.label1 = new System.Windows.Forms.Label(); |
this.textBox1 = new System.Windows.Forms.TextBox(); |
this.listBox1 = new System.Windows.Forms.ListBox(); |
this.groupBox2 = new System.Windows.Forms.GroupBox(); |
this.button5 = new System.Windows.Forms.Button(); |
this.LobbySayTextBox = new System.Windows.Forms.TextBox(); |
this.LobbyTextBox = new System.Windows.Forms.TextBox(); |
this.groupBox3 = new System.Windows.Forms.GroupBox(); |
this.button3 = new System.Windows.Forms.Button(); |
this.button4 = new System.Windows.Forms.Button(); |
this.label2 = new System.Windows.Forms.Label(); |
this.textBox2 = new System.Windows.Forms.TextBox(); |
this.listBox2 = new System.Windows.Forms.ListBox(); |
this.groupBox4 = new System.Windows.Forms.GroupBox(); |
this.label5 = new System.Windows.Forms.Label(); |
this.Nick = new System.Windows.Forms.TextBox(); |
this.HostButton = new System.Windows.Forms.Button(); |
this.label4 = new System.Windows.Forms.Label(); |
this.ConnectButton = new System.Windows.Forms.Button(); |
this.Port = new System.Windows.Forms.TextBox(); |
this.label3 = new System.Windows.Forms.Label(); |
this.Address = new System.Windows.Forms.TextBox(); |
this.statusStrip = new System.Windows.Forms.StatusStrip(); |
this.toolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); |
this.tabControl1 = new System.Windows.Forms.TabControl(); |
this.tabPage1 = new System.Windows.Forms.TabPage(); |
this.groupBox5 = new System.Windows.Forms.GroupBox(); |
this.ActivityTextBox = new System.Windows.Forms.TextBox(); |
this.tabPage2 = new System.Windows.Forms.TabPage(); |
this.groupBox1.SuspendLayout(); |
this.groupBox2.SuspendLayout(); |
this.groupBox3.SuspendLayout(); |
this.groupBox4.SuspendLayout(); |
this.statusStrip.SuspendLayout(); |
this.tabControl1.SuspendLayout(); |
this.tabPage1.SuspendLayout(); |
this.groupBox5.SuspendLayout(); |
this.tabPage2.SuspendLayout(); |
this.SuspendLayout(); |
// |
// groupBox1 |
// |
this.groupBox1.Controls.Add(this.comboBox1); |
this.groupBox1.Controls.Add(this.button2); |
this.groupBox1.Controls.Add(this.button1); |
this.groupBox1.Controls.Add(this.label1); |
this.groupBox1.Controls.Add(this.textBox1); |
this.groupBox1.Controls.Add(this.listBox1); |
this.groupBox1.Location = new System.Drawing.Point(12, 10); |
this.groupBox1.Name = "groupBox1"; |
this.groupBox1.Size = new System.Drawing.Size(256, 296); |
this.groupBox1.TabIndex = 0; |
this.groupBox1.TabStop = false; |
this.groupBox1.Text = "Wing (Them)"; |
// |
// comboBox1 |
// |
this.comboBox1.FormattingEnabled = true; |
this.comboBox1.Location = new System.Drawing.Point(8, 24); |
this.comboBox1.Name = "comboBox1"; |
this.comboBox1.Size = new System.Drawing.Size(240, 21); |
this.comboBox1.TabIndex = 5; |
// |
// button2 |
// |
this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; |
this.button2.Location = new System.Drawing.Point(168, 264); |
this.button2.Name = "button2"; |
this.button2.Size = new System.Drawing.Size(75, 23); |
this.button2.TabIndex = 4; |
this.button2.Text = "Unbind"; |
this.button2.UseVisualStyleBackColor = true; |
// |
// button1 |
// |
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; |
this.button1.Location = new System.Drawing.Point(88, 264); |
this.button1.Name = "button1"; |
this.button1.Size = new System.Drawing.Size(75, 23); |
this.button1.TabIndex = 3; |
this.button1.Text = "Bind"; |
this.button1.UseVisualStyleBackColor = true; |
// |
// label1 |
// |
this.label1.AutoSize = true; |
this.label1.Location = new System.Drawing.Point(8, 232); |
this.label1.Name = "label1"; |
this.label1.Size = new System.Drawing.Size(54, 13); |
this.label1.TabIndex = 2; |
this.label1.Text = "Bound To"; |
// |
// textBox1 |
// |
this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.textBox1.Location = new System.Drawing.Point(72, 228); |
this.textBox1.Name = "textBox1"; |
this.textBox1.ReadOnly = true; |
this.textBox1.Size = new System.Drawing.Size(172, 20); |
this.textBox1.TabIndex = 1; |
// |
// listBox1 |
// |
this.listBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.listBox1.FormattingEnabled = true; |
this.listBox1.Location = new System.Drawing.Point(8, 56); |
this.listBox1.Name = "listBox1"; |
this.listBox1.Size = new System.Drawing.Size(240, 132); |
this.listBox1.TabIndex = 0; |
// |
// groupBox2 |
// |
this.groupBox2.Controls.Add(this.button5); |
this.groupBox2.Controls.Add(this.LobbySayTextBox); |
this.groupBox2.Controls.Add(this.LobbyTextBox); |
this.groupBox2.Location = new System.Drawing.Point(276, 10); |
this.groupBox2.Name = "groupBox2"; |
this.groupBox2.Size = new System.Drawing.Size(256, 296); |
this.groupBox2.TabIndex = 1; |
this.groupBox2.TabStop = false; |
this.groupBox2.Text = "Lobby"; |
// |
// button5 |
// |
this.button5.FlatStyle = System.Windows.Forms.FlatStyle.Flat; |
this.button5.Location = new System.Drawing.Point(208, 264); |
this.button5.Name = "button5"; |
this.button5.Size = new System.Drawing.Size(40, 20); |
this.button5.TabIndex = 2; |
this.button5.UseVisualStyleBackColor = true; |
// |
// LobbySayTextBox |
// |
this.LobbySayTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.LobbySayTextBox.Location = new System.Drawing.Point(8, 264); |
this.LobbySayTextBox.Name = "LobbySayTextBox"; |
this.LobbySayTextBox.Size = new System.Drawing.Size(192, 20); |
this.LobbySayTextBox.TabIndex = 1; |
this.LobbySayTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.LobbySayTextBoxKeyDown); |
// |
// LobbyTextBox |
// |
this.LobbyTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.LobbyTextBox.Location = new System.Drawing.Point(8, 16); |
this.LobbyTextBox.Multiline = true; |
this.LobbyTextBox.Name = "LobbyTextBox"; |
this.LobbyTextBox.ReadOnly = true; |
this.LobbyTextBox.Size = new System.Drawing.Size(240, 240); |
this.LobbyTextBox.TabIndex = 0; |
// |
// groupBox3 |
// |
this.groupBox3.Controls.Add(this.button3); |
this.groupBox3.Controls.Add(this.button4); |
this.groupBox3.Controls.Add(this.label2); |
this.groupBox3.Controls.Add(this.textBox2); |
this.groupBox3.Controls.Add(this.listBox2); |
this.groupBox3.Location = new System.Drawing.Point(540, 10); |
this.groupBox3.Name = "groupBox3"; |
this.groupBox3.Size = new System.Drawing.Size(256, 296); |
this.groupBox3.TabIndex = 2; |
this.groupBox3.TabStop = false; |
this.groupBox3.Text = "Helm (You)"; |
// |
// button3 |
// |
this.button3.FlatStyle = System.Windows.Forms.FlatStyle.Flat; |
this.button3.Location = new System.Drawing.Point(168, 264); |
this.button3.Name = "button3"; |
this.button3.Size = new System.Drawing.Size(75, 23); |
this.button3.TabIndex = 6; |
this.button3.Text = "Remove"; |
this.button3.UseVisualStyleBackColor = true; |
// |
// button4 |
// |
this.button4.FlatStyle = System.Windows.Forms.FlatStyle.Flat; |
this.button4.Location = new System.Drawing.Point(88, 264); |
this.button4.Name = "button4"; |
this.button4.Size = new System.Drawing.Size(75, 23); |
this.button4.TabIndex = 5; |
this.button4.Text = "Add"; |
this.button4.UseVisualStyleBackColor = true; |
// |
// label2 |
// |
this.label2.AutoSize = true; |
this.label2.Location = new System.Drawing.Point(24, 232); |
this.label2.Name = "label2"; |
this.label2.Size = new System.Drawing.Size(35, 13); |
this.label2.TabIndex = 4; |
this.label2.Text = "Name"; |
// |
// textBox2 |
// |
this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.textBox2.Location = new System.Drawing.Point(72, 228); |
this.textBox2.Name = "textBox2"; |
this.textBox2.Size = new System.Drawing.Size(172, 20); |
this.textBox2.TabIndex = 3; |
// |
// listBox2 |
// |
this.listBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.listBox2.FormattingEnabled = true; |
this.listBox2.Location = new System.Drawing.Point(8, 16); |
this.listBox2.Name = "listBox2"; |
this.listBox2.Size = new System.Drawing.Size(240, 184); |
this.listBox2.TabIndex = 1; |
// |
// groupBox4 |
// |
this.groupBox4.Controls.Add(this.label5); |
this.groupBox4.Controls.Add(this.Nick); |
this.groupBox4.Controls.Add(this.HostButton); |
this.groupBox4.Controls.Add(this.label4); |
this.groupBox4.Controls.Add(this.ConnectButton); |
this.groupBox4.Controls.Add(this.Port); |
this.groupBox4.Controls.Add(this.label3); |
this.groupBox4.Controls.Add(this.Address); |
this.groupBox4.Location = new System.Drawing.Point(8, 8); |
this.groupBox4.Name = "groupBox4"; |
this.groupBox4.Size = new System.Drawing.Size(344, 112); |
this.groupBox4.TabIndex = 3; |
this.groupBox4.TabStop = false; |
this.groupBox4.Text = "Connection"; |
// |
// label5 |
// |
this.label5.AutoSize = true; |
this.label5.Location = new System.Drawing.Point(16, 52); |
this.label5.Name = "label5"; |
this.label5.Size = new System.Drawing.Size(29, 13); |
this.label5.TabIndex = 8; |
this.label5.Text = "Nick"; |
// |
// Nick |
// |
this.Nick.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.Nick.Location = new System.Drawing.Point(56, 48); |
this.Nick.Name = "Nick"; |
this.Nick.Size = new System.Drawing.Size(176, 20); |
this.Nick.TabIndex = 7; |
// |
// HostButton |
// |
this.HostButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; |
this.HostButton.Location = new System.Drawing.Point(136, 80); |
this.HostButton.Name = "HostButton"; |
this.HostButton.Size = new System.Drawing.Size(75, 23); |
this.HostButton.TabIndex = 6; |
this.HostButton.Text = "Host"; |
this.HostButton.UseVisualStyleBackColor = true; |
this.HostButton.Click += new System.EventHandler(this.HostButtonClickAsync); |
// |
// label4 |
// |
this.label4.AutoSize = true; |
this.label4.Location = new System.Drawing.Point(240, 24); |
this.label4.Name = "label4"; |
this.label4.Size = new System.Drawing.Size(26, 13); |
this.label4.TabIndex = 3; |
this.label4.Text = "Port"; |
// |
// ConnectButton |
// |
this.ConnectButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; |
this.ConnectButton.Location = new System.Drawing.Point(56, 80); |
this.ConnectButton.Name = "ConnectButton"; |
this.ConnectButton.Size = new System.Drawing.Size(75, 23); |
this.ConnectButton.TabIndex = 5; |
this.ConnectButton.Text = "Connect"; |
this.ConnectButton.UseVisualStyleBackColor = true; |
this.ConnectButton.Click += new System.EventHandler(this.ConnectButtonClickAsync); |
// |
// Port |
// |
this.Port.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.Port.Location = new System.Drawing.Point(272, 20); |
this.Port.Name = "Port"; |
this.Port.Size = new System.Drawing.Size(60, 20); |
this.Port.TabIndex = 2; |
this.Port.Text = "43335"; |
this.Port.Click += new System.EventHandler(this.PortTextBoxClick); |
// |
// label3 |
// |
this.label3.AutoSize = true; |
this.label3.Location = new System.Drawing.Point(8, 24); |
this.label3.Name = "label3"; |
this.label3.Size = new System.Drawing.Size(45, 13); |
this.label3.TabIndex = 1; |
this.label3.Text = "Address"; |
// |
// Address |
// |
this.Address.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.Address.Location = new System.Drawing.Point(56, 20); |
this.Address.Name = "Address"; |
this.Address.Size = new System.Drawing.Size(176, 20); |
this.Address.TabIndex = 0; |
this.Address.Text = "0.0.0.0"; |
this.Address.Click += new System.EventHandler(this.AddressTextBoxClick); |
// |
// statusStrip |
// |
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { |
this.toolStripStatusLabel}); |
this.statusStrip.Location = new System.Drawing.Point(0, 428); |
this.statusStrip.Name = "statusStrip"; |
this.statusStrip.Size = new System.Drawing.Size(800, 22); |
this.statusStrip.TabIndex = 4; |
this.statusStrip.Text = "statusStrip1"; |
// |
// toolStripStatusLabel |
// |
this.toolStripStatusLabel.Name = "toolStripStatusLabel"; |
this.toolStripStatusLabel.Size = new System.Drawing.Size(0, 17); |
// |
// tabControl1 |
// |
this.tabControl1.Controls.Add(this.tabPage1); |
this.tabControl1.Controls.Add(this.tabPage2); |
this.tabControl1.Location = new System.Drawing.Point(0, 64); |
this.tabControl1.Name = "tabControl1"; |
this.tabControl1.SelectedIndex = 0; |
this.tabControl1.Size = new System.Drawing.Size(800, 360); |
this.tabControl1.TabIndex = 5; |
// |
// tabPage1 |
// |
this.tabPage1.Controls.Add(this.groupBox5); |
this.tabPage1.Controls.Add(this.groupBox4); |
this.tabPage1.Location = new System.Drawing.Point(4, 22); |
this.tabPage1.Name = "tabPage1"; |
this.tabPage1.Padding = new System.Windows.Forms.Padding(3); |
this.tabPage1.Size = new System.Drawing.Size(792, 334); |
this.tabPage1.TabIndex = 0; |
this.tabPage1.Text = "Connection"; |
this.tabPage1.UseVisualStyleBackColor = true; |
// |
// groupBox5 |
// |
this.groupBox5.Controls.Add(this.ActivityTextBox); |
this.groupBox5.Location = new System.Drawing.Point(8, 128); |
this.groupBox5.Name = "groupBox5"; |
this.groupBox5.Size = new System.Drawing.Size(776, 200); |
this.groupBox5.TabIndex = 5; |
this.groupBox5.TabStop = false; |
this.groupBox5.Text = "Activity"; |
// |
// ActivityTextBox |
// |
this.ActivityTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.ActivityTextBox.Location = new System.Drawing.Point(8, 16); |
this.ActivityTextBox.Multiline = true; |
this.ActivityTextBox.Name = "ActivityTextBox"; |
this.ActivityTextBox.Size = new System.Drawing.Size(760, 176); |
this.ActivityTextBox.TabIndex = 4; |
// |
// tabPage2 |
// |
this.tabPage2.Controls.Add(this.groupBox1); |
this.tabPage2.Controls.Add(this.groupBox2); |
this.tabPage2.Controls.Add(this.groupBox3); |
this.tabPage2.Location = new System.Drawing.Point(4, 22); |
this.tabPage2.Name = "tabPage2"; |
this.tabPage2.Padding = new System.Windows.Forms.Padding(3); |
this.tabPage2.Size = new System.Drawing.Size(792, 334); |
this.tabPage2.TabIndex = 1; |
this.tabPage2.Text = "Bindings"; |
this.tabPage2.UseVisualStyleBackColor = true; |
// |
// WingManForm |
// |
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); |
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; |
this.ClientSize = new System.Drawing.Size(800, 450); |
this.Controls.Add(this.tabControl1); |
this.Controls.Add(this.statusStrip); |
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; |
this.MaximizeBox = false; |
this.MaximumSize = new System.Drawing.Size(816, 488); |
this.MinimizeBox = false; |
this.MinimumSize = new System.Drawing.Size(816, 488); |
this.Name = "WingManForm"; |
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; |
this.Text = "WingManForm"; |
this.groupBox1.ResumeLayout(false); |
this.groupBox1.PerformLayout(); |
this.groupBox2.ResumeLayout(false); |
this.groupBox2.PerformLayout(); |
this.groupBox3.ResumeLayout(false); |
this.groupBox3.PerformLayout(); |
this.groupBox4.ResumeLayout(false); |
this.groupBox4.PerformLayout(); |
this.statusStrip.ResumeLayout(false); |
this.statusStrip.PerformLayout(); |
this.tabControl1.ResumeLayout(false); |
this.tabPage1.ResumeLayout(false); |
this.groupBox5.ResumeLayout(false); |
this.groupBox5.PerformLayout(); |
this.tabPage2.ResumeLayout(false); |
this.ResumeLayout(false); |
this.PerformLayout(); |
|
} |
|
#endregion |
|
private System.Windows.Forms.GroupBox groupBox1; |
private System.Windows.Forms.GroupBox groupBox2; |
private System.Windows.Forms.GroupBox groupBox3; |
private System.Windows.Forms.ListBox listBox1; |
private System.Windows.Forms.ListBox listBox2; |
private System.Windows.Forms.Label label1; |
private System.Windows.Forms.TextBox textBox1; |
private System.Windows.Forms.TextBox LobbySayTextBox; |
public System.Windows.Forms.TextBox LobbyTextBox; |
private System.Windows.Forms.Label label2; |
private System.Windows.Forms.TextBox textBox2; |
private System.Windows.Forms.Button button2; |
private System.Windows.Forms.Button button1; |
private System.Windows.Forms.Button button3; |
private System.Windows.Forms.Button button4; |
private System.Windows.Forms.Button button5; |
private System.Windows.Forms.GroupBox groupBox4; |
private System.Windows.Forms.Button HostButton; |
private System.Windows.Forms.Label label4; |
private System.Windows.Forms.Button ConnectButton; |
private System.Windows.Forms.TextBox Port; |
private System.Windows.Forms.Label label3; |
private System.Windows.Forms.TextBox Address; |
private System.Windows.Forms.StatusStrip statusStrip; |
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel; |
private System.Windows.Forms.ComboBox comboBox1; |
private System.Windows.Forms.Label label5; |
private System.Windows.Forms.TextBox Nick; |
private System.Windows.Forms.TabControl tabControl1; |
private System.Windows.Forms.TabPage tabPage1; |
private System.Windows.Forms.GroupBox groupBox5; |
public System.Windows.Forms.TextBox ActivityTextBox; |
private System.Windows.Forms.TabPage tabPage2; |
} |
} |
|
/trunk/WingMan/WingManForm.cs |
@@ -0,0 +1,208 @@ |
using System; |
using System.Collections.Generic; |
using System.ComponentModel; |
using System.Data; |
using System.Drawing; |
using System.Globalization; |
using System.Linq; |
using System.Net; |
using System.Text; |
using System.Threading; |
using System.Threading.Tasks; |
using System.Windows.Forms; |
using WingMan.Communication; |
using WingMan.Host; |
|
namespace WingMan |
{ |
public partial class WingManForm : Form |
{ |
private MQTTServer MQTTServer { get; set; } |
|
private MQTTClient MQTTClient { get; set; } |
|
private SemaphoreSlim MQTTServerSemaphore {get; set;} = new SemaphoreSlim(1, 1); |
|
private SemaphoreSlim MQTTClientSemaphore { get; set; } = new SemaphoreSlim(1, 1); |
|
public WingManForm() |
{ |
InitializeComponent(); |
|
MQTTClient = new MQTTClient(this); |
MQTTServer = new MQTTServer(this); |
} |
|
private void AddressTextBoxClick(object sender, EventArgs e) |
{ |
Address.BackColor = Color.Empty; |
} |
|
private void PortTextBoxClick(object sender, EventArgs e) |
{ |
Port.BackColor = Color.Empty; |
} |
|
private async void HostButtonClickAsync(object sender, EventArgs e) |
{ |
// Stop the MQTT server if it is running. |
if (MQTTServer.ServerRunning) |
{ |
await StopServer(); |
toolStripStatusLabel.Text = Properties.Strings.Server_stopped; |
HostButton.BackColor = Color.Empty; |
|
ConnectButton.Enabled = true; |
return; |
} |
|
if (!ValidateAddressPort(out var ipAddress, out var port, out var nick)) |
return; |
|
// Start the MQTT server. |
await StartServer(ipAddress, port, nick); |
toolStripStatusLabel.Text = Properties.Strings.Server_started; |
HostButton.BackColor = Color.Aquamarine; |
|
ConnectButton.Enabled = false; |
} |
|
private bool ValidateAddressPort(out IPAddress address, out int port, out string nick) |
{ |
address = IPAddress.Any; |
port = 0; |
nick = string.Empty; |
|
if (string.IsNullOrEmpty(Address.Text) && |
string.IsNullOrEmpty(Port.Text) && |
string.IsNullOrEmpty(Nick.Text)) |
{ |
Address.BackColor = Color.LightPink; |
Port.BackColor = Color.LightPink; |
Nick.BackColor = Color.LightPink; |
return false; |
} |
|
if (!IPAddress.TryParse(Address.Text, out address)) |
{ |
Address.BackColor = Color.LightPink; |
return false; |
} |
|
if (!uint.TryParse(Port.Text, out var uPort)) |
{ |
Port.BackColor = Color.LightPink; |
return false; |
} |
|
port = (int) uPort; |
|
if (string.IsNullOrEmpty(Nick.Text)) |
{ |
Nick.BackColor = Color.LightPink; |
return false; |
} |
|
nick = Nick.Text; |
|
Address.BackColor = Color.Empty; |
Port.BackColor = Color.Empty; |
Nick.BackColor = Color.Empty; |
|
return true; |
} |
|
private async Task StartServer(IPAddress ipAddress, int port, string nick) |
{ |
await MQTTServerSemaphore.WaitAsync(); |
try |
{ |
await MQTTServer.Start(ipAddress, port, nick); |
} |
finally |
{ |
MQTTServerSemaphore.Release(); |
} |
} |
|
private async Task StopServer() |
{ |
await MQTTServerSemaphore.WaitAsync(); |
try |
{ |
await MQTTServer.Stop(); |
} |
finally |
{ |
MQTTServerSemaphore.Release(); |
} |
} |
|
private async void ConnectButtonClickAsync(object sender, EventArgs e) |
{ |
if (MQTTClient.ClientRunning) |
{ |
await StopClient(); |
ConnectButton.Text = Properties.Strings.Connect; |
ConnectButton.BackColor = Color.Empty; |
|
HostButton.Enabled = true; |
return; |
} |
|
if (!ValidateAddressPort(out var ipAddress, out var port, out var nick)) |
return; |
|
await StartClient(ipAddress, port, nick); |
|
toolStripStatusLabel.Text = Properties.Strings.Client_started; |
ConnectButton.Text = Properties.Strings.Disconnect; |
ConnectButton.BackColor = Color.Aquamarine; |
|
HostButton.Enabled = false; |
} |
|
private async Task StopClient() |
{ |
await MQTTClientSemaphore.WaitAsync(); |
try |
{ |
await MQTTClient.Stop(); |
} |
finally |
{ |
MQTTClientSemaphore.Release(); |
} |
} |
|
private async Task StartClient(IPAddress ipAddress, int port, string nick) |
{ |
await MQTTClientSemaphore.WaitAsync(); |
try |
{ |
await MQTTClient.Start(ipAddress, port, nick); |
} |
finally |
{ |
MQTTClientSemaphore.Release(); |
} |
} |
|
private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e) |
{ |
if (e.KeyCode != Keys.Enter) |
return; |
|
if (MQTTServer.ServerRunning) |
{ |
await MQTTServer.BroadcastLobbyMessage(LobbySayTextBox.Text); |
} |
|
if (MQTTClient.ClientRunning) |
{ |
await MQTTClient.BroadcastLobbyMessage(LobbySayTextBox.Text); |
} |
|
} |
} |
} |
/trunk/WingMan/WingManForm.resx |
@@ -0,0 +1,123 @@ |
<?xml version="1.0" encoding="utf-8"?> |
<root> |
<!-- |
Microsoft ResX Schema |
|
Version 2.0 |
|
The primary goals of this format is to allow a simple XML format |
that is mostly human readable. The generation and parsing of the |
various data types are done through the TypeConverter classes |
associated with the data types. |
|
Example: |
|
... ado.net/XML headers & schema ... |
<resheader name="resmimetype">text/microsoft-resx</resheader> |
<resheader name="version">2.0</resheader> |
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
<value>[base64 mime encoded serialized .NET Framework object]</value> |
</data> |
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
<comment>This is a comment</comment> |
</data> |
|
There are any number of "resheader" rows that contain simple |
name/value pairs. |
|
Each data row contains a name, and value. The row also contains a |
type or mimetype. Type corresponds to a .NET class that support |
text/value conversion through the TypeConverter architecture. |
Classes that don't support this are serialized and stored with the |
mimetype set. |
|
The mimetype is used for serialized objects, and tells the |
ResXResourceReader how to depersist the object. This is currently not |
extensible. For a given mimetype the value must be set accordingly: |
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
that the ResXResourceWriter will generate, however the reader can |
read any of the formats listed below. |
|
mimetype: application/x-microsoft.net.object.binary.base64 |
value : The object must be serialized with |
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter |
: and then encoded with base64 encoding. |
|
mimetype: application/x-microsoft.net.object.soap.base64 |
value : The object must be serialized with |
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
: and then encoded with base64 encoding. |
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
value : The object must be serialized into a byte array |
: using a System.ComponentModel.TypeConverter |
: and then encoded with base64 encoding. |
--> |
<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> |
<metadata name="statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> |
<value>17, 17</value> |
</metadata> |
</root> |