WingMan – Rev
?pathlinks?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
namespace WingMan.Communication
{
public class MQTTClient : IDisposable
{
private WingManForm WingManForm { get; set; }
private IManagedMqttClient Client { get; set; }
public bool ClientRunning { get; set; }
public string Nick { get; set; }
public MQTTClient()
{
Client = new MqttFactory().CreateManagedMqttClient();
}
public MQTTClient(WingManForm wingManForm) : this()
{
WingManForm = wingManForm;
}
public async Task Start(IPAddress ipAddress, int port, string nick)
{
Nick = nick;
var clientOptions = new MqttClientOptionsBuilder()
.WithTcpServer(ipAddress.ToString(), port);
// Setup and start a managed MQTT client.
var options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(clientOptions.Build())
.Build();
BindHandlers();
await Client.SubscribeAsync(
new TopicFilterBuilder()
.WithTopic("lobby")
.Build()
);
await Client.SubscribeAsync(
new TopicFilterBuilder()
.WithTopic("exchange")
.Build()
);
await Client.StartAsync(options);
ClientRunning = true;
}
private void ClientOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
if (e.ApplicationMessage.Topic == "lobby")
{
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload))
{
memoryStream.Position = 0L;
var lobbyMessage = (LobbyMessage)LobbyMessage.XmlSerializer.Deserialize(memoryStream);
UpdateLobbyMessage(lobbyMessage.Nick, lobbyMessage.Message);
}
return;
}
}
private void ClientOnConnected(object sender, MqttClientConnectedEventArgs e)
{
LogActivity(Properties.Strings.Client_connected);
}
private void ClientOnDisconnected(object sender, MqttClientDisconnectedEventArgs e)
{
LogActivity(Properties.Strings.Client_disconnected, e.Exception.Message);
}
private void ClientOnConnectingFailed(object sender, MqttManagedProcessFailedEventArgs e)
{
LogActivity(Properties.Strings.Client_connection_failed, e.Exception.Message);
}
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 Stop()
{
UnbindHandlers();
await Client.StopAsync();
ClientRunning = false;
}
public void Dispose()
{
UnbindHandlers();
Client.StopAsync().Wait();
Client?.Dispose();
}
public void BindHandlers()
{
Client.Connected += ClientOnConnected;
Client.Disconnected += ClientOnDisconnected;
Client.ConnectingFailed += ClientOnConnectingFailed;
Client.ApplicationMessageReceived += ClientOnApplicationMessageReceived;
}
public void UnbindHandlers()
{
Client.Connected -= ClientOnConnected;
Client.Disconnected -= ClientOnDisconnected;
Client.ConnectingFailed -= ClientOnConnectingFailed;
Client.ApplicationMessageReceived -= ClientOnApplicationMessageReceived;
}
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 Client.PublishAsync(new ManagedMqttApplicationMessage
{
ApplicationMessage = new MqttApplicationMessage
{
Payload = memoryStream.ToArray(),
Topic = "lobby"
}
});
}
}
}
}