public void HandleMessage(byte[] message, Socket socket, NetworkStream stream)
        {
            IMessage decodedMessage;

            switch ((MessageIds)message[0])
            {
            case MessageIds.Heartbeat:
                decodedMessage = new HeartbeatMessage();
                decodedMessage.Unpack(message);
                TakeAction((HeartbeatMessage)decodedMessage, socket);
                break;

            case MessageIds.JoinChatroom:
                decodedMessage = new JoinChatroomMessage();
                decodedMessage.Unpack(message);
                TakeAction((JoinChatroomMessage)decodedMessage, socket, stream);
                break;

            case MessageIds.SendChat:
                decodedMessage = new SendChatMessage();
                decodedMessage.Unpack(message);
                TakeAction((SendChatMessage)decodedMessage);
                break;

            default:
                break;
            }
        }
        private void TakeAction(JoinChatroomMessage message, Socket socket, NetworkStream stream)
        {
            var newUser = new User()
            {
                Socket           = socket,
                Stream           = stream,
                Username         = message.Username,
                MissedHeartbeats = 0
            };


            // Send accept/decline message
            var msg = new ChatroomAcceptanceMessage()
            {
                Accepted = 1, MotD = "MotD", WelcomeMessage = "Welcome to the server!"
            };

            lock (_userTracker.TrackerLock)
            {
                if (_userTracker.Users.Any(r => r.Value.Username == message.Username))
                {
                    msg.Accepted         = 0;
                    msg.ReasonForDecline = "Already a user with that username.";
                }
                else
                {
                    _userTracker.Users.Add(socket, newUser);
                }

                msg.ActiveUsers = _userTracker.Users.Select(r => r.Value.Username).ToList();
            }



            var buffer = msg.Pack();

            stream.Write(buffer, 0, buffer.Length);
        }
Beispiel #3
0
        private async Task ConnectTask(string ipAddress, string port, string username)
        {
            var ip      = IPAddress.Parse(ipAddress);
            var intPort = int.Parse(port);

            var ipEndpoint = new IPEndPoint(ip, intPort);

            var client = new TcpClient();

            client.Connect(ipEndpoint);

            var stream = client.GetStream();

            // for testing purposes send over join chat room message
            var msg = new JoinChatroomMessage()
            {
                Username = username
            };

            lock (_queueService.QueueLock)
            {
                _queueService.Enqueue(msg);
            }

            var socket = client.Client;

            while (!(socket.Poll(0, SelectMode.SelectRead) && socket.Available == 0))
            {
                if (stream.DataAvailable)
                {
                    int    twoKiloBytes = 2048;
                    byte[] buffer       = new byte[twoKiloBytes];

                    int messageLength = await stream.ReadAsync(buffer, 0, twoKiloBytes);

                    var flushTask = stream.FlushAsync();

                    byte[] actualMessage = buffer.Take(messageLength).ToArray();

                    await Task.Run(() => _messageHandlingService.HandleMessage(actualMessage, socket));


                    await flushTask;
                }

                if (_queueService.ItemAvailable)
                {
                    // Message to send

                    IMessage message;
                    lock (_queueService.QueueLock)
                    {
                        message = _queueService.Dequeue();
                    }

                    var bytes = message.Pack();
                    await stream.WriteAsync(bytes, 0, bytes.Length);

                    await stream.FlushAsync();
                }
            }

            _eventAggregator.GetEvent <KillHeartbeatEvent>().Publish();
            client.Close();
        }