protected virtual Response callChecked_Connect(AmTcpClient newConnection, string commandString, out string requestedUsername) { requestedUsername = ""; // This function is special and has to do the extra work of splitting and checking the commandstring. string[] commandSplit = CpParseUtilities.SplitMessage(commandString, m_stringDelimiter, 2); // check it is a "connect" request if (commandSplit[0].ToLower() != "connect") { return(new Response(false, "Expected connection request.")); } // check arguments (should be 2) string errMessage = ""; if (!CpParseUtilities.CheckArgCount(commandSplit, 2, 2, ref errMessage)) { return(new Response(false, errMessage)); } // check if name has a colon in it (not allowed) requestedUsername = commandSplit[1]; if (requestedUsername.Contains(m_stringDelimiter)) { return(new Response(false, String.Format("Name shall not contain the delimiter character '{0}'.", m_stringDelimiter))); } // attempt to register the user return(handle_Connect(requestedUsername, newConnection)); }
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(); }
abstract protected Response handle_Connect(string username, AmTcpClient newConnection);