WingMan – Rev
?pathlinks?
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;
namespace WingMan.Host
{
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()
{
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, 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" });
}
}
}
}