// Constructor
        public AmTcpDemuxer(SslEgg egg)
        {
            RemoteEndPoint = (IPEndPoint)egg.TcpSocket.Client.RemoteEndPoint;
            m_client       = egg.SslStream;
            m_stream       = new ReadAggregatorWritePassthrough(m_client);

            m_serviceThread = new Thread(serviceLoop);
            m_serviceThread.Start();
        }
        protected override async Task ftClientServiceLoopAsync(SslEgg egg)
        {
            FtClient client = new FtClient(egg.SslStream);

            // shortcut lambda
            Func <Response, Task <bool> > lSendResponseAsync = async(response) =>
            {
                return(await CpServersideBase.SendResponseAsync(client.SerializerAsync, response.Success, response.Message));
            };

            // the command string read from client
            var tup = await client.DeserializerAsync.DeserializeAsync("");

            bool   stillConnected = tup.Item1;
            string commandString  = tup.Item2;

            if (!stillConnected)
            {
                goto exit;
            }

            // an array of strings parsed from the sent command string by splitting by colon :
            // hard-coded max 10 substrings. Change if needed.
            string[] commandSplit = CpParseUtilities.SplitMessage(commandString, m_stringDelimiter, 10);

            switch (commandSplit[0].ToLower())
            {
            case "file_up":
            {
                Tuple <bool, Response> res = await callChecked_FileUpAsync(client, commandSplit);

                if (res.Item1)          // client still connected
                {
                    await lSendResponseAsync(res.Item2);
                }
                break;
            }

            case "file_down":
            {
                Tuple <bool, Response> res = await callChecked_FileDownAsync(client, commandSplit);

                if (res.Item1)          // client still connected
                {
                    await lSendResponseAsync(res.Item2);
                }
                break;
            }

            default:
                break;
            }

exit:
            client.Close();
        }
Exemple #3
0
        // constructor
        public CpClientsideBase(SslEgg egg)
        {
            m_server                  = new AmTcpDemuxer(egg);
            m_serverSerializer        = new SerializationAdapter(m_server.WriteStream);
            m_serverDeserializer      = new DeserializationAdapter(m_server.ReadStream);
            m_serverEventDeserializer = new DeserializationAdapter(m_server.ReadEventStream);

            m_eventChannelReadThread = new Thread(eventChannelReadLoop);
            m_eventChannelReadThread.Start();
        }
        protected async Task clientServiceLoop(SslEgg egg)
        {
            SslStream sslClient = egg.SslStream;

            // Determine if client is for chat or file transfer.
            // Read one byte right from the stream
            int            amountRead = 0;
            ConnectionMode mode;

            try
            {
                byte[] buffer = new byte[1];
                amountRead = await sslClient.ReadAsync(buffer, 0, 1);

                mode = (ConnectionMode)buffer[0];
            }
            catch
            {
                goto exit_fail;
            }

            if (amountRead != 1)  // client disconnected
            {
                goto exit_fail;
            }

            switch (mode)
            {
            case ConnectionMode.CHAT_PROTOCOL:
                await cpClientServiceLoopAsync(egg);

                return;

            case ConnectionMode.FILE_TRANSFER:
                await ftClientServiceLoopAsync(egg);

                return;

            default:
                Debug.Assert(false);      // should never happen
                goto exit_fail;
            }

exit_fail:
            sslClient.Close();
            return;
        }
        private async Task cpClientServiceLoopAsync(SslEgg egg)
        {
            AmTcpClient client = new AmTcpClient(egg);

            // shortcut lambda
            Func <Response, Task <bool> > lSendResponseAsync = async(response) =>
            {
                return(await SendResponseAsync(client.Serializer, response.Success, response.Message));
            };

            // establish connection / register user
            string username;

            {
                // read from the new client (expecting a "connect" commandstring).
                var tup = await client.Deserializer.DeserializeAsync("");

                bool   stillConnected = tup.Item1;
                string commandString  = tup.Item2;

                if (!stillConnected)
                {
                    Logging.DebugWriteLine("Client connected but disconnected before trying to register.");
                    client.Close();
                    return;
                }
                // parse the command string and register the user
                Response res = callChecked_Connect(client, commandString, out username);
                await lSendResponseAsync(res);  // don't need to check result as a disconnected client will be detected upon first read

                if (!res.Success)
                {
                    Logging.DebugWriteLine(String.Format("Unable to register new client '{0}'. {1}", username, res.Message));
                    client.Close();
                    return;
                }

                Logging.DebugWriteLine(String.Format("Client '{0}' connected. {1}", username, client.RemoteEndPoint.ToString()));
            }

            while (true)
            {
                // the command string read from client
                var tup = await client.Deserializer.DeserializeAsync("");

                bool   stillConnected = tup.Item1;
                string commandString  = tup.Item2;

                if (!stillConnected)
                {
                    // remove the user from various data structures
                    Response result = handle_Disconnect(username);
                    Logging.DebugWriteLine(String.Format("Client {0} disconnected.", username));
                    if (!result.Success)
                    {
                        Logging.DebugWriteLine(result.Message);
                    }
                    goto exit_while;
                }

                // an array of strings parsed from the sent command string by splitting by colon :
                // hard-coded max 10 substrings. Change if needed.
                string[] commandSplit = CpParseUtilities.SplitMessage(commandString, m_stringDelimiter, 10);


                switch (commandSplit[0].ToLower())
                {
                case "disconnect":
                {
                    Response result = callChecked_Disconnect(commandSplit, username);
                    await lSendResponseAsync(result);

                    if (result.Success)
                    {
                        Logging.DebugWriteLine(String.Format("Client {0} disconnected gracefully.", username));
                        goto exit_while;
                    }
                    Logging.DebugWriteLine(String.Format("From server: Client {0} requested disconnect but was denied. {1}", username, result.Message));
                    break;
                }

                case "create_room":
                {
                    Response result = callChecked_CreateRoom(commandSplit);
                    await lSendResponseAsync(result);

                    if (result.Success)
                    {
                        Logging.DebugWriteLine(String.Format("Client {0} created room '{1}'.", username, commandSplit[1]));
                    }
                    break;
                }

                case "delete_room":
                {
                    Response result = await callChecked_DeleteRoom(commandSplit);
                    await lSendResponseAsync(result);

                    if (result.Success)
                    {
                        Logging.DebugWriteLine(String.Format("Client {0} deleted room '{1}'.", username, commandSplit[1]));
                    }
                    break;
                }

                case "list_rooms":
                {
                    Response result = callChecked_ListRooms(commandSplit);
                    await lSendResponseAsync(result);

                    break;
                }

                case "subscribe_room":
                {
                    Response result = callChecked_SubscribeRoom(commandSplit, username);
                    await lSendResponseAsync(result);

                    break;
                }

                case "unsubscribe_room":
                {
                    Response result = callChecked_UnsubscribeRoom(commandSplit, username);
                    await lSendResponseAsync(result);

                    break;
                }

                case "list_room_members":
                {
                    Response result = callChecked_ListRoomMembers(commandSplit);
                    await lSendResponseAsync(result);

                    break;
                }

                case "send_message_room":
                {
                    Response result = await callChecked_MessageRoomAsync(commandSplit, username);
                    await lSendResponseAsync(result);

                    break;
                }

                case "send_message_personal":
                {
                    Response result = await callChecked_MessagePersonalAsync(commandSplit, username);
                    await lSendResponseAsync(result);

                    break;
                }

                default:
                    await lSendResponseAsync(new Response(false, "Unknown command."));

                    Logging.DebugWriteLine(String.Format("Client sent unknown command. '{0}'", commandString));
                    break;
                }
            }

exit_while:
            // cleanup socket resources
            client.Close();
        }
 // by default this feature is not implemented
 virtual protected Task ftClientServiceLoopAsync(SslEgg egg)
 {
     egg.SslStream.Close();
     return(Task.CompletedTask);
 }
 // Constructor
 public AmTcpMuxer(SslEgg egg)
 {
     RemoteEndPoint = (IPEndPoint)egg.TcpSocket.Client.RemoteEndPoint;
     m_client       = egg.SslStream;
     m_stream       = new ReadAggregatorWritePassthrough(m_client);
 }