예제 #1
0
        /// <summary>
        /// When a tcpClient is accepted, we set up a new ChatConnection
        /// and use that for stream read/ write. The ChatConnection is then set to start listening to.
        /// At the end, the server is set to accept further tcpClient.
        /// </summary>
        /// <param name="ar"></param>
        private void AcceptCallback(IAsyncResult ar)
        {
            var server = (TcpListener)ar.AsyncState;

            try
            {
                var client     = server.EndAcceptTcpClient(ar);
                var connection = new ChatConnection(client)
                {
                    EndPoint = client.Client.RemoteEndPoint.ToString()
                };
                connections.Add(connection);

                var evMsg = "connection from " + connection.EndPoint;
                ShowAndLog(LogLevel.Info, evMsg);

                connection.BeginRead(ReadCallback, connection);

                // Set server to accept client mode.
                server.BeginAcceptTcpClient(AcceptCallback, server);
            }
            catch (Exception ex)
            {
                Console.WriteLine("In AcceptCallback: " + ex);
            }
        }
예제 #2
0
        /// <summary>
        /// Disconnecting a certain connection when the associated client (user) is leaving.
        /// This event is logged.
        /// </summary>
        /// <param name="disconnecting"></param>
        private void Disconnect(ChatConnection disconnecting)
        {
            lock (connections)
            {
                connections.Remove(disconnecting);
            }
            disconnecting.CloseConnection();

            var msg = $"{disconnecting.UserName} left";

            ShowAndLog(LogLevel.Info, msg);
        }
예제 #3
0
        /// <summary>
        /// When connected to the server, create a ChatConnection to handle read/write to stream.
        /// Start to listen for messages from server with BeginRead.
        /// At last, send the current user name to the server for update.
        /// </summary>
        /// <param name="ar"></param>
        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                var client = (TcpClient)ar.AsyncState;
                client.EndConnect(ar);
                Connection = new ChatConnection(client)
                {
                    UserName = ClientName
                };
                Connection.BeginRead(ReadCallback, Connection);

                Connection.BeginWrite(WriteCallback, Connection, $"/r {ClientName}");
            }
            catch (Exception ex)
            {
                Console.WriteLine("In ConnectCallback: " + ex);
            }
        }
예제 #4
0
        /// <summary>
        /// Can handle disconnect of client ("/q"),
        /// can handle rename of user name ("/r"),
        /// can handle user names request ("/u"),
        /// can handle whisper from one user to another ("/w"), and
        /// can handle send message to all ("/a").
        /// </summary>
        /// <param name="message"></param>
        /// <param name="sender"></param>
        private void ParseMessage(string message, ChatConnection sender)
        {
            var lines   = message.Split(' ').ToList();
            var command = lines[0].ToLowerInvariant();

            if (command.Equals("/q"))
            {
                Disconnect(sender);
                var msg = $"/i {GetUsernamesAsString()}";
                lock (connections)
                {
                    foreach (var connection in connections)
                    {
                        connection.BeginWrite(WriteCallback, connection, msg);
                    }
                }
            }
            else if (command.Equals("/r"))
            {
                if (lines.Count == 2)
                {
                    sender.UserName = lines[1];
                    var evMsg = $"{sender.EndPoint} renamed to {sender.UserName}";
                    ShowAndLog(LogLevel.Info, evMsg);
                    var msg = $"/i {GetUsernamesAsString()}";
                    lock (connections)
                    {
                        foreach (var connection in connections)
                        {
                            connection.BeginWrite(WriteCallback, connection, evMsg);
                        }
                    }
                }
            }
            else if (command.Equals("/u"))
            {
                var msg = $"{sender.UserName} ask for usernames";
                ShowAndLog(LogLevel.Info, msg);
                sender.BeginWrite(WriteCallback, sender, $"/i {GetUsernamesAsString()}");
            }
            else if (command.Equals("/w"))
            {
                if (lines.Count > 2)
                {
                    var msg      = string.Join(" ", lines.GetRange(2, lines.Count - 2));
                    var receiver = connections.FirstOrDefault(c => c.UserName == lines[1]);
                    if (receiver != null && sender.UserName != receiver.UserName)
                    {
                        var evMsg = $"{sender.UserName}->{receiver.UserName}:{msg}";
                        ShowAndLog(LogLevel.Info, evMsg);
                        receiver.BeginWrite(WriteCallback, receiver, $"{sender.UserName}:{msg}");
                        sender.BeginWrite(WriteCallback, sender, $"+ {message}");
                        return;
                    }
                }
                sender.BeginWrite(WriteCallback, sender, $"- {message}");
            }
            else if (command.Equals("/a"))
            {
                if (lines.Count > 1)
                {
                    var msg   = string.Join(" ", lines.GetRange(1, lines.Count - 1));
                    var evMsg = $"{sender.UserName}->all:{msg}";
                    ShowAndLog(LogLevel.Info, evMsg);
                    msg = sender.UserName + ":" + string.Join(" ", lines.GetRange(1, lines.Count - 1));
                    foreach (var connection in connections)
                    {
                        if (connection.UserName != sender.UserName)
                        {
                            connection.BeginWrite(WriteCallback, connection, msg);
                        }
                    }
                    sender.BeginWrite(WriteCallback, sender, $"+ {message}");
                    return;
                }
                sender.BeginWrite(WriteCallback, sender, $"- {message}");
            }
        }