WingMan – Rev 7

Subversion Repositories:
Rev:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using WingMan.Communication;

namespace WingMan.Lobby
{
    public class LobbyMessageSynchronizer : IDisposable
    {
        public delegate void LobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e);

        public LobbyMessageSynchronizer(MQTTCommunication MQTTCommunication, TaskScheduler taskScheduler,
            CancellationToken cancellationToken)
        {
            this.MQTTCommunication = MQTTCommunication;
            CancellationToken = cancellationToken;
            TaskScheduler = taskScheduler;

            MQTTCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
        }

        private MQTTCommunication MQTTCommunication { get; }

        private CancellationToken CancellationToken { get; }
        private TaskScheduler TaskScheduler { get; }

        public void Dispose()
        {
            MQTTCommunication.OnMessageReceived -= MqttCommunicationOnOnMessageReceived;
        }

        public event LobbyMessageReceived OnLobbyMessageReceived;

        private async void MqttCommunicationOnOnMessageReceived(object sender,
            MqttApplicationMessageReceivedEventArgs e)
        {
            if (e.ApplicationMessage.Topic != "lobby")
                return;

            using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload))
            {
                var lobbyMessage = (LobbyMessage) LobbyMessage.XmlSerializer.Deserialize(memoryStream);

                await Task.Delay(0)
                    .ContinueWith(
                        _ => OnLobbyMessageReceived?.Invoke(sender,
                            new LobbyMessageReceivedEventArgs(lobbyMessage.Nick, lobbyMessage.Message)),
                        CancellationToken, TaskContinuationOptions.None, TaskScheduler);
            }
        }

        public async Task Broadcast(string message)
        {
            using (var memoryStream = new MemoryStream())
            {
                LobbyMessage.XmlSerializer.Serialize(memoryStream, new LobbyMessage
                {
                    Nick = MQTTCommunication.Nick,
                    Message = message
                });

                memoryStream.Position = 0L;

                await MQTTCommunication.Broadcast("lobby", memoryStream.ToArray()).ConfigureAwait(false);
            }
        }
    }
}