예제 #1
0
        private void onReceive(IAsyncResult ar)
        {
            try
            {
                Socket clientSocket = (Socket)ar.AsyncState;
                clientSocket.EndReceive(ar);

                CommandData request = new CommandData(m_buffer);
                CommandData response = new CommandData();
                byte[] responseData;

                response.CommandName = request.CommandName;
                response.UserName = request.UserName;

                switch (request.CommandName)
                {
                    case CommandType.Login:
                        ClientInfo clientInfo = new ClientInfo();
                        clientInfo.Socket = clientSocket;
                        clientInfo.Login = request.UserName;

                        if (m_clients.TryAdd(clientInfo.Login, clientInfo))
                        {
                            response.Message = String.Format("====={0} has joined the chat=====", clientInfo.Login);
                        }
                        else
                        {
                            response.CommandName = CommandType.Error;
                            response.UserName = null;
                            response.Message = String.Format("Name {0} is already taken! Choose another one", request.UserName);

                            responseData = response.ToByteArray();

                            clientSocket.BeginSend(responseData, 0, responseData.Length, SocketFlags.None, new AsyncCallback(onSend), clientSocket);
                            Console.WriteLine(String.Format("*login {0} is already taken error*", request.UserName));
                            break;
                        }
                        break;

                    case CommandType.Logout:
                        ClientInfo clt = new ClientInfo();

                        if (m_clients.TryRemove(request.UserName, out clt))
                        {
                            clientSocket.Close();
                            response.Message = String.Format("====={0} has left the room=====", clt.Login);
                        }
                        break;

                    case CommandType.Message:
                        response.Message = String.Format("{0}: {1}", request.UserName, request.Message);
                        logMessageAsync(request.Message);
                        break;

                    case CommandType.UsersList:
                        response.CommandName = CommandType.UsersList;
                        response.UserName = null;
                        response.Message = String.Join(",", m_clients.Select(el => el.Key));

                        responseData = response.ToByteArray();

                        clientSocket.BeginSend(responseData, 0, responseData.Length, SocketFlags.None, new AsyncCallback(onSend), clientSocket);
                        break;

                    case CommandType.History:
                        response.CommandName = CommandType.History;
                        response.UserName = null;
                        response.Message = File.ReadAllText(m_logFilePath);

                        responseData = response.ToByteArray();

                        clientSocket.BeginSend(responseData, 0, responseData.Length, SocketFlags.None, new AsyncCallback(onSend), clientSocket);
                        Console.WriteLine("History sent to " + request.UserName);
                        break;
                }

                if (response.CommandName != CommandType.UsersList &&
                    response.CommandName != CommandType.History &&
                    response.CommandName != CommandType.Error)
                {
                    responseData = response.ToByteArray();

                    foreach (var clientInfo in m_clients)
                    {
                        Socket sct = clientInfo.Value.Socket;
                        if (sct != clientSocket || response.CommandName != CommandType.Login)
                            sct.BeginSend(responseData, 0, responseData.Length, SocketFlags.None, new AsyncCallback(onSend), sct);
                    }

                    Console.WriteLine(response.Message);
                }

                if (request.CommandName != CommandType.Logout && response.CommandName != CommandType.Error)
                {
                    clientSocket.BeginReceive(m_buffer, 0, m_buffer.Length, SocketFlags.None, new AsyncCallback(onReceive), clientSocket);
                }
            }
            catch (Exception ex)
            {
                Utils.LogException(ex);
            }
        }
예제 #2
0
        public void Dispose()
        {
            CommandData request = new CommandData(CommandType.Error, "Server is not available", null);
            byte[] data = request.ToByteArray();

            foreach (var clientInfo in m_clients)
            {
                Socket sct = clientInfo.Value.Socket;
                if (sct != null && sct.Connected)
                {
                    sct.Send(data);
                }
            }

            m_clients.Clear();

            if (m_serverSocket != null)
            {
                m_serverSocket.Close();
                m_serverSocket.Dispose();
                m_serverSocket = null;
            }
        }