/// <summary> /// Establishes a connection to the given UNIX socket file /// </summary> /// <param name="initMessage">Init message to send to the server</param> /// <param name="socketPath">Path to the UNIX socket file</param> /// <param name="cancellationToken">Optional cancellation token</param> /// <returns>Asynchronous task</returns> /// <exception cref="IncompatibleVersionException">API level is incompatible</exception> /// <exception cref="IOException">Connection mode is unavailable</exception> /// <exception cref="OperationCanceledException">Operation has been cancelled</exception> /// <exception cref="SocketException">Connection has been closed</exception> protected async Task Connect(ClientInitMessage initMessage, string socketPath, CancellationToken cancellationToken) { // Create a new connection UnixDomainSocketEndPoint endPoint = new UnixDomainSocketEndPoint(socketPath); _unixSocket.Connect(endPoint); // Verify server init message ServerInitMessage ownMessage = new ServerInitMessage(); ServerInitMessage serverMessage = await Receive <ServerInitMessage>(cancellationToken); if (serverMessage.Version < ownMessage.Version) { throw new IncompatibleVersionException($"Incompatible API version (need {ownMessage.Version}, got {serverMessage.Version}"); } Id = serverMessage.Id; // Switch mode await Send(initMessage, cancellationToken); BaseResponse response = await ReceiveResponse(cancellationToken); if (!response.Success) { ErrorResponse errorResponse = (ErrorResponse)response; throw new IOException($"Could not set connection type {_connectionMode} ({errorResponse.ErrorType}: {errorResponse.ErrorMessage})"); } }
/// <summary> /// Establishes a connection to the given UNIX socket file /// </summary> /// <param name="initMessage">Init message to send to the server</param> /// <param name="socketPath">Path to the UNIX socket file</param> /// <param name="cancellationToken">Optional cancellation token</param> /// <returns>Asynchronous task</returns> /// <exception cref="IncompatibleVersionException">API level is incompatible</exception> /// <exception cref="IOException">Connection mode is unavailable</exception> /// <exception cref="OperationCanceledException">Operation has been cancelled</exception> /// <exception cref="SocketException">Connection has been closed</exception> protected async Task Connect(ClientInitMessage initMessage, string socketPath, CancellationToken cancellationToken) { // Create a new connection UnixDomainSocketEndPoint endPoint = new UnixDomainSocketEndPoint(socketPath); _unixSocket.Connect(endPoint); // Read the server init message ServerInitMessage ownMessage = new ServerInitMessage(); ServerInitMessage serverMessage = await Receive <ServerInitMessage>(cancellationToken); Id = serverMessage.Id; // Switch mode initMessage.Version = Defaults.ProtocolVersion; await Send(initMessage, cancellationToken); // Check the result BaseResponse response = await ReceiveResponse(cancellationToken); if (!response.Success) { ErrorResponse errorResponse = (ErrorResponse)response; if (errorResponse.ErrorType == nameof(IncompatibleVersionException)) { throw new IncompatibleVersionException(errorResponse.ErrorMessage); } throw new IOException($"Could not set connection type {_connectionMode} ({errorResponse.ErrorType}: {errorResponse.ErrorMessage})"); } }
/// <summary> /// Establishes a connection to the given UNIX socket file /// </summary> /// <param name="initMessage">Init message to send to the server</param> /// <param name="socketPath">Path to the UNIX socket file</param> /// <param name="cancellationToken">Optional cancellation token</param> /// <returns>Asynchronous task</returns> /// <exception cref="IncompatibleVersionException">API level is incompatible</exception> /// <exception cref="IOException">Connection mode is unavailable</exception> protected async Task Connect(ClientInitMessage initMessage, string socketPath, CancellationToken cancellationToken) { // Create a new connection UnixDomainSocketEndPoint endPoint = new UnixDomainSocketEndPoint(socketPath); _unixSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); _unixSocket.Connect(endPoint); // Make sure we can deserialize incoming data _networkStream = new NetworkStream(_unixSocket); _streamReader = new StreamReader(_networkStream); InitReader(); // Verify server init message ServerInitMessage expectedMessage = new ServerInitMessage(); ServerInitMessage serverMessage = await Receive <ServerInitMessage>(cancellationToken); if (serverMessage.Version < expectedMessage.Version) { throw new IncompatibleVersionException($"Incompatible API version (expected {expectedMessage.Version}, got {serverMessage.Version}"); } Id = serverMessage.Id; // Switch mode await Send(initMessage); BaseResponse response = await ReceiveResponse <object>(cancellationToken); if (!response.Success) { ErrorResponse errorResponse = (ErrorResponse)response; throw new IOException($"Could not set connection type {_connectionMode} ({errorResponse.ErrorType}: {errorResponse.ErrorMessage})"); } }
protected override void StateUpdate() { if (m_awaitedInitMessage != null) { m_simulationBuffer = m_awaitedInitMessage.SimulationBuffer.Value; m_playerIDs = new List <int>(); foreach (int id in m_awaitedInitMessage.PlayerCharacters.Value.Keys) { m_playerIDs.Add(id); } #if DEBUG_LOG Debug.Log("Client received confirmation that server is about to start game with " + m_playerIDs.Count + " players and " + m_simulationBuffer + " simulation buffer ticks"); #endif // DEBUG_LOG #if DEBUG_LOG Debug.Log("Starting to load world."); #endif // DEBUG_LOG StartCoroutine(LoadWorldCoroutine(m_awaitedInitMessage.CellInfo2DArray.Value)); m_awaitedInitMessage = null; } if (m_serverSentSignal) { m_TCPClient.Unsubscribe(this); m_serverSentSignal = false; OnGameStart?.Invoke(); ClientSyncState.m_playState.Init(m_simulationBuffer.Value, m_playerIDs, new ClientGameInfo(m_clientCharacters.Values)); m_currentState = ClientSyncState.m_playState; } }
protected override void StateAwake() { ClientListUpdate = new ClientListUpdateEvent(); m_awaitedInitMessage = null; ClientSyncState.m_lobbyState = this; m_serverSentSignal = false; LoadPercentage = 0; m_clientCharacters = new Dictionary <int, CharacterData>(); }
public RfbConnection(TcpClient client, Pipe pipe, ServerInitMessage serverInitMessage, MonitorSnippet?section) { Tcp = client; IncomingPacketsPipe = pipe; FramebufferWidth = serverInitMessage.FramebufferWidth; FramebufferHeight = serverInitMessage.FramebufferHeight; PixelFormat = serverInitMessage.PixelFormat; Name = serverInitMessage.Name; Section = section; }
public void ReceivePacket(tcp.TCPToolkit.Packet packet) { ServerStartsMessage ready = common.serialization.IConvertible.CreateFromBytes <ServerStartsMessage>(packet.Data.ArraySegment()); if (ready != null) { #if DEBUG_LOG Debug.Log("Received server start message."); #endif // DEBUG_LOG m_serverSentSignal = true; return; } // loads other players in lobby, receives message from server indicating a new player joined CharacterListMessage clientList = common.serialization.IConvertible.CreateFromBytes <CharacterListMessage>(packet.Data.ArraySegment()); if (clientList != null) { Debug.Log("Received " + clientList.PlayerCharacters.Value.Count + " characters from server"); foreach (common.serialization.types.String id in clientList.PlayerCharacters.Value.Values) { Debug.Log("Fetching character " + id.Value + " from microservice"); // fetch character data from microservice string strID = id.Value; m_characterService.GetCharacter(strID, (CharacterData character) => { Debug.Log("Got character from " + character.PlayerID + " : " + character.Name); m_clientCharacters[character.PlayerID.GetHashCode()] = character; ClientListUpdate.Invoke(new List <CharacterData>(m_clientCharacters.Values)); }); } return; } System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); ServerInitMessage start = common.serialization.IConvertible.CreateFromBytes <ServerInitMessage>(packet.Data.ArraySegment()); watch.Stop(); if (start != null) { #if DEBUG_LOG Debug.Log("Time elapsed for world deserialization : " + watch.ElapsedMilliseconds + " ms"); #endif // DEBUG_LOG m_awaitedInitMessage = start; return; } }
protected override void StateUpdate() { lock (m_lock) { if (EveryoneIsReady() && !m_awaitingClientLoadWorld) { m_UDPServer.Unsubscribe(this); common.world.cellType.CellInfo[,] cellInfoArray = m_worldGenerator.GetCellInfoArray(); ServerInitMessage message = new ServerInitMessage(m_simulationBuffer, m_clientCharacters, cellInfoArray); foreach (int id in m_clientCharacters.Keys) { m_TCPServer.Send(message.GetBytes(), id); } Debug.Log("Waiting for clients to load their worlds"); m_awaitingClientLoadWorld = true; } if (EveryoneIsWorldLoaded()) { m_readyToStartGame = true; m_awaitingClientLoadWorld = false; } } if (m_readyToStartGame) { m_readyToStartGame = false; ServerStartsMessage message = new ServerStartsMessage(); Debug.Log("Starting game."); foreach (int id in m_clientCharacters.Keys) { m_TCPServer.Send(message.GetBytes(), id); } m_TCPServer.Unsubscribe(this); m_gameplayState.Init(m_clientCharacters, m_simulationBuffer); m_currentState = m_gameplayState; } }