public static void LobbyServiceHUB(ExtendedConcurrentQueue <byte[]> provider, string[] request, Dictionary <int, object> paramDictionary) { int service = int.Parse(request[0]); object answer = null; switch (service) { case NetworkObjectParameters.LobbyServerPlayerUIDRequest: answer = PlayerHandler.GenerateUIDForPlayerLogin(request[1]); break; case NetworkObjectParameters.LobbyServerLoginRequest: answer = PlayerHandler.LobbyLoginRequest(request[1]); break; case NetworkObjectParameters.GameServerRegisterRequest: answer = ServerInformationHandler.RefreshGameServerStatusRequest(request[1], paramDictionary); break; case NetworkObjectParameters.LobbyServerServerListRequest: ServerInformationHandler.GameServerListRequest(provider); return; } provider.Enqueue(service, answer); }
public static T Peek <T>(this ExtendedConcurrentQueue <T> queue) { T tmpValue = default; lock (queue) queue.TryPeek(out tmpValue); return(tmpValue); }
public static void Enqueue(this ExtendedConcurrentQueue <byte[]> queue, int service, object serviceObject) { string serviceObjectJSON = ObjectWrapper.Serialize(serviceObject); byte[] req = ObjectWrapper.ConvertObjectToByteArray($"{service}|{serviceObjectJSON}"); lock (queue) queue.Enqueue(req); }
void ServiceRegisterOperationThread() { TcpListener listener = new TcpListener(IPAddress.Any, port); while (true) { try { listener.Start(); while (true) { Dictionary <int, object> paramDictionary = new Dictionary <int, object>(); ExtendedConcurrentQueue <byte[]> queue = new ExtendedConcurrentQueue <byte[]>(); Socket socket = listener.AcceptSocket(); queue.OnEnqueueAction = (item) => AsyncSendMessage(socket, queue, paramDictionary); string threadName = $"{socket.RemoteEndPoint}"; Thread consumerThread = new Thread(() => ConsumerThread(socket, threadName, queue, paramDictionary)); consumerThread.Name = threadName; consumerThread.Start(); } } catch (Exception ex) { listener.Stop(); Console.WriteLine($"Message: {ex.Message}"); } } }
void AsyncSendMessage(Socket socket, ExtendedConcurrentQueue <byte[]> queue, Dictionary <int, object> paramDictionary) { try { while (!socket.Connected) { Thread.Sleep(100); } while (!queue.IsEmpty) { byte[] request = queue.Dequeue(); Array.Resize(ref request, bufferSize); int sent = 0; while (sent < bufferSize) { sent += socket.Send(request, sent, bufferSize - sent, SocketFlags.None); } } } catch (Exception ex) { Console.WriteLine($"Message: {ex.Message}"); } }
public ClientServiceProvider(string serverAddress, int serverPort, int bufferSize, Action <ClientServiceProvider, string[]> consumerAction) { this.serverAddress = serverAddress; this.serverPort = serverPort; this.bufferSize = bufferSize; this.consumerAction = consumerAction; RequestQueue = new ExtendedConcurrentQueue <byte[]>(); }
public static void GameServerListRequest(ExtendedConcurrentQueue <byte[]> provider) { try { lock (LobbyServerObjects.ServerInformationList) { foreach (GameServerInformation si in LobbyServerObjects.ServerInformationList) { provider.Enqueue(NetworkObjectParameters.LobbyServerServerListRequest, si); } } } catch (Exception) { } }
public static void LoginServiceHUB(ExtendedConcurrentQueue <byte[]> provider, string[] request, Dictionary <int, object> paramDictionary) { int service = int.Parse(request[0]); object answer = null; switch (service) { case NetworkObjectParameters.LoginServerLoginAttemptRequest: PlayerHandler.StartListeningPlayerLoginAttempt(provider, request[1]); return; case NetworkObjectParameters.LoginServerAccountCreationRequest: answer = PlayerHandler.RegistrationAttempt(request[1]); break; } provider.Enqueue(service, answer); }
public static void StartListeningPlayerLoginAttempt(ExtendedConcurrentQueue <byte[]> provider, string param) { try { PlayerController pc = new PlayerController(); Player deserializedPlayer = ObjectWrapper.Deserialize <Player>(param); Player player = pc.LoginPlayer(deserializedPlayer); Player answer = null; if (player != null) { ClientServiceProvider csp = new ClientServiceProvider( NetworkObjectParameters.LobbyServerInformation.ServerLocalAddress, NetworkObjectParameters.LobbyServerInformation.ServerPort, NetworkObjectParameters.LobbyServerBufferSize, (_provider, _request) => { answer = ObjectWrapper.Deserialize <Player>(_request[1]); }); csp.StartOperation(); csp.RequestQueue.Enqueue(NetworkObjectParameters.LobbyServerPlayerUIDRequest, player); while (answer == null) { Thread.Sleep(100); } csp.StopOperation(); deserializedPlayer.Nickname = answer.Nickname; } Console.WriteLine($"- Request for: {deserializedPlayer.Nickname} - {deserializedPlayer.Password} - Player " + ((answer == null) ? "not " : "") + "found"); if (answer == null) { provider.Enqueue(NetworkObjectParameters.LoginServerLoginAttemptRequest, null); return; } // Preparing Player Information Stream Dictionary <AvatarCategory, HashSet <int> > ownedAvatars = pc.RetrievePlayerAvatarList(player); provider.Enqueue(NetworkObjectParameters.LoginServerLoginAttemptRequest, player); if (ownedAvatars != null) { foreach (KeyValuePair <AvatarCategory, HashSet <int> > kvp in ownedAvatars) { //For safety reasons, the maximum integer stream size must be 300 integers. const int maximumSize = 300; for (int i = 0; i < kvp.Value.Count; i += maximumSize) { provider.Enqueue(NetworkObjectParameters.LoginServerLoginAttemptRequest, (int)kvp.Key, kvp.Value.Skip(i).Take(maximumSize).ToList()); } } } //Sends the "EOF" to client provider.Enqueue(NetworkObjectParameters.LoginServerLoginAttemptRequest, 0, null); } catch (Exception ex) { Console.WriteLine($"Error: {ex}"); throw ex; } }
public static void GameServiceHUB(ExtendedConcurrentQueue <byte[]> provider, string[] request, Dictionary <int, object> paramDictionary) { int service; object answer = null; service = (request != null) ? int.Parse(request[0]) : NetworkObjectParameters.ServerProcessingError; PlayerSession playerSession = null; if (paramDictionary.ContainsKey(NetworkObjectParameters.PlayerSession)) { playerSession = (PlayerSession)paramDictionary[NetworkObjectParameters.PlayerSession]; } switch (service) { // Server Information case NetworkObjectParameters.GameServerMetadataRequest: answer = NetworkObjectParameters.GameServerInformation; break; // Connection case NetworkObjectParameters.GameServerPlayerAccessRequest: answer = GameClientProvider.GameServerPlayerAccessRequest(request[1], paramDictionary, provider); break; // Server Information Request case NetworkObjectParameters.GameServerSearchPlayer: GameClientProvider.GameServerSearchPlayer(request[1]); break; // Game List / Requests case NetworkObjectParameters.GameServerRoomListCreateRoom: answer = GameClientProvider.GameServerRoomListCreateRoom(request[1], playerSession); break; case NetworkObjectParameters.GameServerRoomListRequestList: GameClientProvider.GameServerRoomListRequestList(request[1], provider); return; case NetworkObjectParameters.GameServerRoomListRoomEnter: answer = GameClientProvider.GameServerRoomListRoomEnter(request[1], playerSession); break; // Game Room / Requests case NetworkObjectParameters.GameServerRoomLeaveRoom: answer = GameClientProvider.GameServerRoomLeaveRoom(playerSession); break; case NetworkObjectParameters.GameServerRoomReadyRoom: GameClientProvider.GameServerRoomReadyRoom(playerSession); return; case NetworkObjectParameters.GameServerRoomChangePrimaryMobile: GameClientProvider.GameServerRoomChangePrimaryMobile(request[1], playerSession); return; case NetworkObjectParameters.GameServerRoomChangeTeam: GameClientProvider.GameServerRoomChangeTeam(playerSession); return; case NetworkObjectParameters.GameServerRoomChangeMap: GameClientProvider.GameServerRoomChangeMap(request[1], playerSession); return; case NetworkObjectParameters.GameServerRoomRefreshLoadingPercentage: GameClientProvider.GameServerRoomRefreshLoadingPercentage(request[1], playerSession); return; case NetworkObjectParameters.GameServerRoomStartInGameScene: GameClientProvider.GameServerRoomStartInGameScene(playerSession); return; // InGame / Requests case NetworkObjectParameters.GameServerInGameStartMatch: GameClientProvider.GameServerInGameStartMatch(playerSession); return; case NetworkObjectParameters.GameServerInGameRefreshSyncMobile: GameClientProvider.GameServerInGameRefreshSyncMobile(request[1], playerSession); return; case NetworkObjectParameters.GameServerInGameRequestNextPlayerTurn: answer = GameClientProvider.GameServerInGameRequestNextPlayerTurn(playerSession); break; case NetworkObjectParameters.GameServerInGameRequestShot: GameClientProvider.GameServerInGameRequestShot(request[1], playerSession); return; case NetworkObjectParameters.GameServerInGameRequestDeath: GameClientProvider.GameServerInGameRequestDeath(request[1], playerSession); return; case NetworkObjectParameters.GameServerInGameRequestItemUsage: GameClientProvider.GameServerInGameRequestItemUsage(request[1], playerSession); return; case NetworkObjectParameters.GameServerInGameRequestDamage: GameClientProvider.GameServerInGameRequestDamage(request[1], playerSession); return; case NetworkObjectParameters.GameServerInGameRequestLoseTurn: GameClientProvider.GameServerInGameRequestLoseTurn(request[1], playerSession); return; // Messaging / Room List Chat Requests case NetworkObjectParameters.GameServerChatEnter: GameClientProvider.GameServerChatEnterRequest(request[1], playerSession); return; case NetworkObjectParameters.GameServerChatLeave: GameClientProvider.GameServerChatLeave(playerSession); return; case NetworkObjectParameters.GameServerChatSendPlayerMessage: GameClientProvider.GameServerChatRoomSendMessage(request[1], playerSession); return; // Avatar Shop case NetworkObjectParameters.GameServerAvatarShopBuyAvatarGold: answer = GameClientProvider.GameServerAvatarShopBuyAvatar(request[1], playerSession, PaymentMethod.Gold); break; case NetworkObjectParameters.GameServerAvatarShopBuyAvatarCash: answer = GameClientProvider.GameServerAvatarShopBuyAvatar(request[1], playerSession, PaymentMethod.Cash); break; case NetworkObjectParameters.GameServerAvatarShopUpdatePlayerData: GameClientProvider.GameServerAvatarShopUpdatePlayerMetadata(request[1], playerSession); return; } provider.Enqueue(service, answer); }
protected virtual void ConsumerThread(Socket socket, string threadName, ExtendedConcurrentQueue <byte[]> queue, Dictionary <int, object> paramDictionary) { try { byte[] response = new byte[bufferSize]; while (true) { int received = 0; while (received < bufferSize) { received += socket.Receive(response, received, bufferSize - received, SocketFlags.None); /* * If you received 0 bytes, that usually means the sender has closed their send socket. In a Socket, the send and receive channels are separate; I expect what * is happening is that your send (their receive) is still open and available, hence clientSocket.Connected returning true (you can still send them a reply), * but: they closed their send (your receive) as soon as they sent their payload (this is common, to indicate the end of a batch). Basically, you just need to * detect the 0-byte receive, and treat that as the end: no more data will ever be incoming once you have had a non-positive reply from receive. So just write any * response you need to write (they can still be listening, even though they will never speak again), and shutdown the socket. * Source: https://stackoverflow.com/questions/19221199/c-sharp-socket-receive-continuously-receives-0-bytes-and-does-not-block-in-the-l */ if (received == 0) { return; } } Console.WriteLine(ObjectWrapper.ConvertByteArrayToObject <string>(response)); string resp = ObjectWrapper.ConvertByteArrayToObject <string>(response); if (resp == null) { return; } consumerAction(queue, resp.Split('|'), paramDictionary); } } catch (ThreadInterruptedException ex) { Console.WriteLine($"Message: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"Message: {ex.Message}"); } finally { onDisconnect?.Invoke(paramDictionary); Console.WriteLine($"{threadName} was terminated."); try { socket.Dispose(); } catch (Exception) { } } }