private async Task <Result> InvokeOnServerShutdown() { _logger.LogDebug("Invoking OnServerShutdown event on port {Port}", Port); if (OnServerShutdown != null) { await OnServerShutdown.Invoke(this); } return(Result.Success()); }
public string ReceiveNewMessageFromServer() { try { while (true) { NetworkStream stream = client.GetStream(); byte[] data = new byte[65536]; int bytes = stream.Read(data, 0, data.Length); string res = Encoding.UTF8.GetString(data, 0, bytes); HandleMessage(res); OnMessageReceivedFromServer?.Invoke(this, new ClientSendMessageEventArgs() { Time = DateTime.Now, Message = res }); } } catch { OnServerShutdown?.Invoke(this, new EventArgs()); IsConnected = false; return(null); } }
public void Update() { if (m_state == ManagerState.Connected && m_prevState == ManagerState.Connecting) { // client just connected: invoke event handlers OnClientConnected?.Invoke(); } else if (!m_connectionRequested && m_prevState == ManagerState.Connected) { // client about to disconnect: invoke event handlers OnClientDisconnecting?.Invoke(); // transition to actual disconnect m_state = ManagerState.Disconnecting; } if (m_client.IsConnected()) { // process server updates and events here so entity updates are processed in the render loop m_client.ProcessServerUpdates(); } // relay events to handlers in render loop: // registered clients lock (m_registeredClients) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingClients.AddRange(m_registeredClients); m_registeredClients.Clear(); } if (m_processingClients.Count > 0) { // process newly registered client events foreach (ClientData client in m_processingClients) { OnClientRegistered?.Invoke(client); } m_processingClients.Clear(); } // unregistered clients lock (m_unregisteredClients) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingClients.AddRange(m_unregisteredClients); m_unregisteredClients.Clear(); } if (m_processingClients.Count > 0) { // process newly unregistered client events foreach (ClientData client in m_processingClients) { OnClientUnregistered?.Invoke(client); } m_processingClients.Clear(); } // publishing entities lock (m_publishedEntities) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingEntities.AddRange(m_publishedEntities); m_publishedEntities.Clear(); } if (m_processingEntities.Count > 0) { // process published entity events OnEntitiesPublished?.Invoke(m_processingEntities); m_processingEntities.Clear(); } // revoking entities lock (m_revokedEntities) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingEntities.AddRange(m_revokedEntities); m_revokedEntities.Clear(); } if (m_processingEntities.Count > 0) { // process revoked entity events OnEntitiesRevoked?.Invoke(m_processingEntities); m_processingEntities.Clear(); } lock (m_controlledEntities) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingEntities.AddRange(m_controlledEntities); m_controlledEntities.Clear(); } if (m_processingEntities.Count > 0) { // process control-changed entity events OnEntityControlChanged?.Invoke(m_processingEntities); m_processingEntities.Clear(); } // broadcasts lock (m_broadcasts) { // transfer list content to temp list to avoid deadlock through event handler using client functions m_processingBroadcasts.AddRange(m_broadcasts); m_broadcasts.Clear(); } if (m_processingBroadcasts.Count > 0) { // handle broadcasts foreach (Broadcast broadcast in m_processingBroadcasts) { OnClientBroadcastReceived?.Invoke(broadcast); } m_processingBroadcasts.Clear(); } lock (m_serverShutdown) { if (m_serverShutdown.Count > 0) { bool restart = m_serverShutdown[0]; OnServerShutdown?.Invoke(restart); StartCoroutine(AutoDisconnectAsync(restart)); m_serverShutdown.Clear(); } } m_prevState = m_state; }
public void Dispose() { Shutdown(); OnServerShutdown?.Invoke(this); }
internal static void RunServerShutdown() => OnServerShutdown?.Invoke();
/// <summary> /// Starts local server based on given or local configuration. /// </summary> public static void StartServer(QNetConfiguration configuration = null) { if (IsServerActive) { throw new InvalidOperationException( "QNet is unable to start server while there is already active instance of server."); } if (configuration == null) { configuration = new QNetConfiguration(); } var hostIsActive = IsHostActive; Server = new QNetServer(); Server = InternalStartPeer(Server, configuration, () => { QNetHandlerStack.RegisterServerHandlers(Server); OnServerRegisterHeaders?.Invoke(); }); OnServerPrepare?.Invoke(); Server.OnBeforeMessage += message => { // server should always send the server frame to the client! message.Write(QNetTime.ServerFrame); }; Server.OnConnectionAuthorizing += (QNetConnection connection, QNetMessageWriter writer, ref bool refuse) => { writer.WriteInt32(QNetTime.TickRate); writer.WriteUInt32(QNetTime.ServerFrame); OnServerAuthorizePlayer?.Invoke(connection, writer, ref refuse); }; Server.OnConnectionReady += reader => { // read player nickname and create its QNetPlayer instance var nickname = reader.ReadString(); var token = reader.ReadUInt32(); var version = reader.ReadString(); if (JEMBuild.BuildVersion != version) { JEMLogger.LogError( $"Newly received connection don't have right version of the game -> {version} ( is {JEMBuild.BuildVersion} )"); Server.CloseConnection(reader.Connection, "InvalidBuildVersion"); } else { if (IsHostActive && (reader.Connection.ConnectionIdentity == 0 || reader.Connection.ConnectionIdentity == Client.ConnectionIdentity)) { HostClientConnection = reader.Connection; JEMLogger.Log("QNetUnity received host client connection."); } if (QNetPlayer.GetQNetPlayerByToken(token) != null) { JEMLogger.LogError("Newly received connection is using already used token. Disconnecting!"); Server.CloseConnection(reader.Connection, "TokenAlreadyInUse"); return; } var qNetPlayer = QNetPlayer.CreateQNetPlayer(reader.Connection.ConnectionIdentity, nickname, token); if (qNetPlayer == null) { JEMLogger.LogError( "Newly received connection don't have his QNetPlayer instance. Disconnecting!"); Server.CloseConnection(reader.Connection, "InternalQNetPlayerError"); return; } OnServerNewPlayer?.Invoke(qNetPlayer, reader); QNetServerConnectionInit.PrepareNewConnection(reader.Connection); } }; Server.OnConnectionLost += (connection, reason) => { var qNetPlayer = QNetPlayer.GetQNetPlayer(connection); if (qNetPlayer != null) // if QNetPlayer of this connection not exists, just ignore { OnServerPlayerLost?.Invoke(qNetPlayer, reason); // the only thing to do here is to tag player as not ready (if ready) if (qNetPlayer.Ready) { qNetPlayer.TagAsNotReady(); } // and remove QNetPlayer from local machine QNetPlayer.DestroyQNetPlayer(qNetPlayer); } }; Server.OnServerStop += reason => { // server has been stopped, try to de-initialize game if (!ShuttingDownByApplicationQuit) { QNetGameInitializer.DeInitialize(() => { OnServerShutdown?.Invoke(hostIsActive); }); } else { OnServerShutdown?.Invoke(hostIsActive); } IsServerActive = false; IsHostActive = false; }; IsServerActive = true; OnServerStarted?.Invoke(); }