private void OnClientConnectedCallback(ulong clientId) { Debug.LogFormat("Client connected: {0} (is server: {1})", clientId, NetworkManager.Singleton.IsServer); if (NetworkManager.Singleton.IsServer) { OnClientConnected?.Invoke(); } }
void INetEventListener.OnPeerConnected(NetPeer peer) { Logger.Log("[C] Connected to server: " + peer.EndPoint + " (" + peer.Id + ")"); _server = peer; // Tell listeners we connected OnClientConnected?.Invoke(); _logicTimer.Start(); }
void AcceptSocket(IAsyncResult result) { var server = ((TcpListener)result.AsyncState); client = ((TcpListener)result.AsyncState).EndAcceptSocket(result); Console.WriteLine("Connection accepted from " + client.RemoteEndPoint); connected = true; OnClientConnected.Invoke(client); }
void Connection_Thread() { while (m_bIsRunning) { this.LogData("Connecting to Server..."); try { #if DEBUG if (m_strOnionHost == "127.0.0.1") { MasterClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); MasterClient.Connect((EndPoint) new IPEndPoint(IPAddress.Parse(m_strOnionHost), m_iOnionPort)); } else #endif MasterClient = this.ConnectSocksProxy(this.m_strTorHost, (short)this.m_iTorPort, this.m_strOnionHost, (short)this.m_iOnionPort, MasterClient); if (MasterClient == null) { /* * ToDo: * - Write to log (Failed to connect) */ this.LogData("Failed to connect to Server"); Thread.Sleep(10 * 1000); continue; } this.LogData("Connected to Server successfully."); this.m_bIsConnected = true; MasterStream = new SslStream(new NetworkStream(MasterClient), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); this.LogData("SSL Handshake started."); MasterStream.AuthenticateAsClient("Client"); this.LogData("SSL Handshake finished."); Byte[] arr_bBuffer = new Byte[MasterClient.ReceiveBufferSize]; MasterStream.BeginRead(arr_bBuffer, 0, arr_bBuffer.Length, new AsyncCallback(SSL_BeginRead_Callback), arr_bBuffer); if (OnClientConnected != null) { OnClientConnected.Invoke(); } while (this.m_bIsConnected) { Thread.Sleep(10 * 1000); } } catch { } Thread.Sleep(10 * 1000); } }
/// <summary> /// Client connected handler /// </summary> /// <param name="async">The IAsyncResult</param> private void OnClientConnect(IAsyncResult async) { Socket socket = _listener.EndAccept(async); Session session = new Session(socket, SessionType.SERVER_TO_CLIENT); OnClientConnected?.Invoke(session, _port); session.WaitForData(); _listener.BeginAccept(OnClientConnect, null); }
public override void OnClientConnect(NetworkConnection conn) { Debug.Log("[LobbyNetworkManager] Connected to server"); base.OnClientConnect(conn); OnClientConnected?.Invoke(); if (SceneManager.GetActiveScene().buildIndex == 0) { ClientScene.AddPlayer(conn); } }
/// <summary> /// Se déclanche quand un nouvelle utilisateur se connecte à la communication socket /// </summary> private void OnSocketListenerClientConnected(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { #warning indiquer un id au nouveau client SocketClient client = new SocketClient("", args.Socket); client.OnClientDisconnected += OnClientDisconnected; client.OnMessageReceived += OnClientMessageReceived; _clients.Add(client); _someClientConnected = true; OnClientConnected?.Invoke(this, client.Id); }
public override void OnAwake() { base.OnAwake(); // create client & server client = new Telepathy.Client(clientMaxMessageSize); server = new Telepathy.Server(serverMaxMessageSize); // tell Telepathy to use Unity's Debug.Log Telepathy.Log.Info = Debug.Log; Telepathy.Log.Warning = Debug.LogWarning; Telepathy.Log.Error = Debug.LogError; // client hooks // other systems hook into transport events in OnCreate or // OnStartRunning in no particular order. the only way to avoid // race conditions where telepathy uses OnConnected before another // system's hook (e.g. statistics OnData) was added is to wrap // them all in a lambda and always call the latest hook. // (= lazy call) client.OnConnected = () => OnClientConnected.Invoke(); client.OnData = (segment) => OnClientDataReceived.Invoke(segment, Channels.DefaultReliable); client.OnDisconnected = () => OnClientDisconnected.Invoke(); // client configuration client.NoDelay = NoDelay; client.SendTimeout = SendTimeout; client.ReceiveTimeout = ReceiveTimeout; client.SendQueueLimit = clientSendQueueLimit; client.ReceiveQueueLimit = clientReceiveQueueLimit; // server hooks // other systems hook into transport events in OnCreate or // OnStartRunning in no particular order. the only way to avoid // race conditions where telepathy uses OnConnected before another // system's hook (e.g. statistics OnData) was added is to wrap // them all in a lambda and always call the latest hook. // (= lazy call) server.OnConnected = (connectionId) => OnServerConnected.Invoke(connectionId); server.OnData = (connectionId, segment) => OnServerDataReceived.Invoke(connectionId, segment, Channels.DefaultReliable); server.OnDisconnected = (connectionId) => OnServerDisconnected.Invoke(connectionId); // server configuration server.NoDelay = NoDelay; server.SendTimeout = SendTimeout; server.ReceiveTimeout = ReceiveTimeout; server.SendQueueLimit = serverSendQueueLimitPerConnection; server.ReceiveQueueLimit = serverReceiveQueueLimitPerConnection; // allocate enabled check only once enabledCheck = () => Enabled; Debug.Log("TelepathyTransport initialized!"); }
public void StartListening() { Console.WriteLine("Remote Console ready."); ClientService ClientTask; // Client Connections Pool ClientConnectionPool ConnectionPool = new ClientConnectionPool(); // Client Task to handle client requests ClientTask = new ClientService(ConnectionPool); ClientTask.Start(); TcpListener listener = new TcpListener(IPAddress.Any, portNum); try { listener.Start(); int ClientNbr = 0; // Start listening for connections. while (true) { TcpClient handler = listener.AcceptTcpClient(); if (handler != null) { Console.WriteLine("Client#{0} accepted!", ++ClientNbr); // An incoming connection needs to be processed. var clientHandler = new ClientHandler(ClientNbr, handler); OnClientConnected?.Invoke(clientHandler); clientHandler.OnMessageReceived += ClientHandler_OnMessageReceived; ConnectionPool.Enqueue(clientHandler); } else { break; } } listener.Stop(); // Stop client requests handling ClientTask.Stop(); } catch (Exception e) { Console.WriteLine(e.ToString()); } }
public override async void ClientConnect(string address) { DisposeClient(); IPAddress[] addresses = Dns.GetHostAddresses(address); IPAddress ip = null; foreach (var tmp in addresses) { if (tmp.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { ip = tmp; } } ServerConnectSettings setting; if (!string.IsNullOrWhiteSpace(m_RsaXmlPath)) { var xml = Resources.Load <TextAsset>(m_RsaXmlPath); setting = ServerConnectSettings.FromXML(xml.text, new IPEndPoint(ip, m_Port)); } else { setting = new ServerConnectSettings { EndPoint = new IPEndPoint(ip, m_Port), }; } var task = m_ClientTask = Connection.ConnectToServer(setting); try { var conn = await task; if (task == m_ClientTask) { m_ClientConn = conn; OnClientConnected?.Invoke(); } else { conn.Dispose(); } } catch (Exception) { if (task == m_ClientTask) { OnClientDisconnected?.Invoke(); } } }
public SimpleTcpServer(int port, OnServerStart onStart, int bufferSize, OnClientConnected onClientConnected , OnConnectionError onConnectionError, OnClientRequest onClientRequest, string endOfFileTag) { _onStart = onStart; _bufferSize = bufferSize; _onClientConnected = onClientConnected; _onConnectionError = onConnectionError; _onClientRequest = onClientRequest; _endOfFileTag = endOfFileTag; Port = port; _activeClients = new List <TcpClient>(); _tasks = new List <Task>(); }
public override void OnClientConnect(NetworkConnection conn) { // base.OnClientConnect(conn); if (!clientLoadedScene) { if (!ClientScene.ready) { ClientScene.Ready(conn); } ClientScene.AddPlayer(conn); } OnClientConnected?.Invoke(); }
private void PlayerConnected(Player player) { player.ConnectionId = NextConnectionId; NextConnectionId += 1; Console.WriteLine(DateTime.Now.ToString() + $" Player Connected. Total Players Connected: {Players.Model.Count}"); SendKey(player); //Chama evento OnClientConnected OnClientConnected?.Invoke(player); }
private void ProcessInitialPacket(Packet packet, IPEndPoint endPoint) { UInt32 availableConnectionId; byte[] data; // Unsupported version. Version negotiation packet is sent only on initial connection. All other packets are dropped. (5.2.2 / 16th draft) if (packet.Version != QuicVersion.CurrentVersion || !QuicVersion.SupportedVersions.Contains(packet.Version)) { VersionNegotiationPacket vnp = _packetCreator.CreateVersionNegotiationPacket(); data = vnp.Encode(); _client.Send(data, data.Length, endPoint); return; } InitialPacket cast = packet as InitialPacket; InitialPacket ip = _packetCreator.CreateInitialPacket(0, cast.SourceConnectionId); // Protocol violation if the initial packet is smaller than the PMTU. (pt. 14 / 16th draft) if (cast.Encode().Length < QuicSettings.PMTU) { ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.PROTOCOL_VIOLATION, "PMTU have not been reached.")); } else if (ConnectionPool.AddConnection(cast.SourceConnectionId, out availableConnectionId) == true) { // Tell the peer the available connection id ip.SourceConnectionId = (byte)availableConnectionId; // We're including the maximum possible stream id during the connection handshake. (4.5 / 16th draft) ip.AttachFrame(new MaxStreamsFrame(QuicSettings.MaximumStreamId, StreamType.ServerBidirectional)); } else { // Not accepting connections. Send initial packet with CONNECTION_CLOSE frame. // TODO: Buffering. The server might buffer incomming 0-RTT packets in anticipation of late delivery InitialPacket. // Maximum buffer size should be set in QuicSettings. ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.SERVER_BUSY, "The server is too busy to process your request.")); } data = ip.Encode(); int dataSent = _client.Send(data, data.Length, endPoint); if (dataSent > 0) { // Create a QuicContext to represent the connected client. QuicContext context = new QuicContext(_client, endPoint); ConnectionPool.AttachContext(ip.SourceConnectionId, context); OnClientConnected?.Invoke(context); } }
public override void OnAwake() { base.OnAwake(); // logging // Log.Info should use Debug.Log if enabled, or nothing otherwise // (don't want to spam the console on headless servers) if (debugLog) { Log.Info = Debug.Log; } else { Log.Info = _ => {} }; Log.Warning = Debug.LogWarning; Log.Error = Debug.LogError; // client client = new KcpClient( () => OnClientConnected.Invoke(), (message) => OnClientDataReceived.Invoke(message, Channels.DefaultReliable), () => OnClientDisconnected.Invoke() ); // server server = new KcpServer( (connectionId) => OnServerConnected.Invoke(connectionId), (connectionId, message) => OnServerDataReceived.Invoke(connectionId, message, Channels.DefaultReliable), (connectionId) => OnServerDisconnected.Invoke(connectionId), NoDelay, Interval, FastResend, CongestionWindow, SendWindowSize, ReceiveWindowSize ); if (statisticsLog) { Task.Run(async() => { await Task.Delay(100); OnLogStatistics(); await Task.Delay(100); }); //InvokeRepeating(nameof(OnLogStatistics), 1, 1); } Debug.Log("KcpTransport initialized!"); }
private void OnClientDataReceive(ArraySegment <byte> data, int channel) { try { var rawData = data.Array; int pos = data.Offset; OpCodes opcode = (OpCodes)rawData.ReadByte(ref pos); switch (opcode) { case OpCodes.ServerPublicKey: _serverPublicKey = rawData.ReadBytes(ref pos); pos = 0; _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.ClientPublicKey); _clientSendBuffer.WriteBytes(ref pos, _keyPair.PublicKey); CommunicationTransport.ClientSend(Channels.Reliable, new ArraySegment <byte>(_clientSendBuffer, 0, pos)); if (showDebugLogs) { Debug.Log($"<color=green>MONKE | CLIENT RECIEVED SERVER PUBLIC KEY!</color>"); } OnClientConnected?.Invoke(); break; case OpCodes.Data: _readBuffer = rawData.ReadBytes(ref pos); _nonce = rawData.ReadBytes(ref pos); _encryptionBuffer = PublicKeyBox.Open(_readBuffer, _nonce, _keyPair.PrivateKey, _serverPublicKey); OnClientDataReceived?.Invoke(new ArraySegment <byte>(_encryptionBuffer), channel); if (showDebugLogs) { Debug.Log($"<color=green>MONKE | CLIENT DATA | RAW DATA: " + _readBuffer.Length + " DECRYPTED DATA LENGTH: " + _encryptionBuffer.Length + "</color>" + " <color=yellow>DELTA: " + (_readBuffer.Length - _encryptionBuffer.Length) + "</color>"); } break; } } catch (Exception e) { Debug.LogError("Error: " + e); } }
public ThreadedConnectionManager(int threadCount, int updateTimeMs = 1000) { this.threadCount = threadCount; threadPool = new ThreadWithClients[threadCount]; for (int i = 0; i < threadCount; ++i) { threadPool[i] = new ThreadWithClients(); var threadWitchClients = threadPool[i]; threadWitchClients.Thread = new Thread(() => { while (true) { Parallel.For(0, threadWitchClients.Clients.Count, async(index, _) => { var client = threadWitchClients.Clients[index]; try { if (client.IsFirstUpdate) { OnClientConnected?.Invoke(this, new ClientStateChangedEventArgs(client)); client.IsFirstUpdate = false; await client.FirstUpdateAsync(); } else { await client.UpdateAsync(); } } catch { client.Dispose(); client.IsConnected = false; OnClientDisconnected?.Invoke(this, new ClientStateChangedEventArgs(client)); } }); threadWitchClients.Clients.RemoveAll((c => !c.IsConnected)); Thread.Sleep(updateTimeMs); } }); threadWitchClients.Thread.Start(); } }
public override void OnClientConnect(NetworkConnection conn) { //Called on each client when they connect initially if (!clientLoadedScene) { if (!ClientScene.ready) { ClientScene.Ready(conn); } ClientScene.AddPlayer(conn); } //Invoking the action for Lobby OnClientConnected?.Invoke(); }
private void IncomingMessageTypeStatusChanged(PeerType t, NetIncomingMessage message) { // ReSharper disable once SwitchStatementMissingSomeCases switch (message.SenderConnection.Status) { case NetConnectionStatus.Connected: OnClientConnected?.Invoke(t, message.SenderConnection); break; case NetConnectionStatus.Disconnecting: OnClientDisonnect?.Invoke(t, message.SenderConnection); break; } }
public static void Init(bool isServer = false, bool isClient = false, bool isSimulated = false) { IsServer = isServer ? true : IsServer; IsClient = isClient ? true : IsClient; IsSimulated = isSimulated ? true : IsSimulated; if (isSimulated) { if (NetLogFilter.logInfo) { Debug.Log("Transport Layer Initialized: Simulation"); } return; } if (IsServer && server == null) { // server server = new KcpServer( (connectionId) => OnServerConnected.Invoke(connectionId), (connectionId, message) => OnServerDataReceived.Invoke(connectionId, message, (int)UDPChannels.Reliable), (connectionId) => OnServerDisconnected.Invoke(connectionId), NoDelay, Interval, FastResend, CongestionWindow, SendWindowSize, ReceiveWindowSize ); if (NetLogFilter.logInfo) { Debug.Log("Transport Layer Initialized: Server"); } } if (IsClient && client == null) { // client client = new KcpClient( () => OnClientConnected.Invoke(), (message) => OnClientDataReceived.Invoke(message, (int)UDPChannels.Reliable), () => OnClientDisconnected.Invoke() ); if (NetLogFilter.logInfo) { Debug.Log("Transport Layer Initialized: Client"); } } }
private void SortClientMessages(SNetworkMessage _message) { if (_message.type == EMessageType.Unknown) { Debug.LogError("Server sent an Unknow message"); return; } if (_message.type == EMessageType.ConnectionSuccessful) { clientID = int.Parse(_message.JSON); Debug.Log($"The Server told me I'm client n°{clientID}"); OnClientConnected?.Invoke(); isConnected = true; } if (_message.type == EMessageType.Instantiate) { SMessageInstantiate msg = JsonUtility.FromJson <SMessageInstantiate>(_message.JSON); InstantiateSyncObject(msg.prefabName, msg.GUID, msg.position, msg.rotation, msg.parentName); return; } if (_message.type == EMessageType.UpdateTransform) { SMessageUpdateTransform msg = JsonUtility.FromJson <SMessageUpdateTransform>(_message.JSON); NetworkSynchronizer.Instance.SyncDown(msg.GUID, msg.position, msg.rotation, msg.scale); return; } //only for Chess if (_message.type == EMessageType.Grab) { NetworkSynchronizer.Instance.GetSMBByGUID(_message.JSON).GetComponent <Piece>().Grab(); } if (_message.type == EMessageType.Ungrab) { NetworkSynchronizer.Instance.GetSMBByGUID(_message.JSON).GetComponent <Piece>().UnGrab(); } if (_message.type == EMessageType.UpdateGrab) { SMessageVector3 msg = JsonUtility.FromJson <SMessageVector3>(_message.JSON); NetworkSynchronizer.Instance.GetSMBByGUID(msg.GUID).GetComponent <Piece>().SyncDownGrab(msg.vector); } if (_message.type == EMessageType.UpdateHand) { NetworkSynchronizer.Instance.SyncHandsDown(JsonUtility.FromJson <SMessageHand>(_message.JSON)); } }
public bool ProcessClientMessage() { if (clientId == -1) { return(false); } int connectionId; int channel; int receivedSize; NetworkEventType networkEvent = NetworkTransport.ReceiveFromHost(clientId, out connectionId, out channel, clientReceiveBuffer, clientReceiveBuffer.Length, out receivedSize, out error); // note: 'error' is used for extra information, e.g. the reason for // a disconnect. we don't necessarily have to throw an error if // error != 0. but let's log it for easier debugging. // // DO NOT return after error != 0. otherwise Disconnect won't be // registered. NetworkError networkError = (NetworkError)error; if (networkError != NetworkError.Ok) { string message = "NetworkTransport.Receive failed: hostid=" + clientId + " connId=" + connectionId + " channelId=" + channel + " error=" + networkError; OnClientError.Invoke(new Exception(message)); } // raise events switch (networkEvent) { case NetworkEventType.ConnectEvent: OnClientConnected.Invoke(); break; case NetworkEventType.DataEvent: byte[] data = new byte[receivedSize]; Array.Copy(clientReceiveBuffer, data, receivedSize); OnClientDataReceived.Invoke(data); break; case NetworkEventType.DisconnectEvent: OnClientDisconnected.Invoke(); break; default: return(false); } return(true); }
// client callbacks //////////////////////////////////////////////////// void OnLibuvClientConnected(TcpStream handle, Exception exception) { // close if errors (AFTER setting up onClosed callback!) if (exception != null) { Debug.Log($"libuv cl: client error {exception}"); handle.Dispose(); return; } // Mirror event OnClientConnected.Invoke(); Debug.Log($"libuv cl: client connected."); }
public SteamworksTransport() { _client = new P2PClient(); _server = new P2PServer(); _client.OnConnected.AddListener(() => OnClientConnected?.Invoke()); _client.OnData.AddListener(bytes => { OnClientDataReceived?.Invoke(bytes); }); _client.OnError.AddListener(exception => { OnClientError?.Invoke(exception); }); _client.OnDisconnect.AddListener(() => { OnClientDisconnected?.Invoke(); }); _server.OnConnect.AddListener(id => { OnServerConnected?.Invoke(id); }); _server.OnData.AddListener((id, data) => { OnServerDataReceived?.Invoke(id, data); }); _server.OnError.AddListener((id, exception) => { OnServerError?.Invoke(id, exception); }); _server.OnDisconnect.AddListener(id => { OnServerDisconnected?.Invoke(id); }); }
/// <summary> /// Called on the client when connected to a server. /// </summary> /// <param name="conn">Connection to the server.</param> #pragma warning disable 618 public override void OnClientConnect(NetworkConnection conn) #pragma warning restore 618 { base.OnClientConnect(conn); if (conn.lastError == NetworkError.Ok) { Debug.Log("Successfully connected to server."); } else { Debug.LogError("Connected to server with error: " + conn.lastError); } OnClientConnected?.Invoke(); }
private void ListenForMessages() { _pipeStream.ReadAsync(_msgBuff, 0, _msgBuff.Length).ContinueWith(t => { if (t.Result == 0) { OnClientDisconnected?.Invoke(this, null); return; } var decodedData = Encoding.Default.GetString(_msgBuff, 0, t.Result); var parsedMessage = PipeMessage.Deserialize(decodedData); switch (parsedMessage.MessageType) { case MessageType.Init: if (!_busy) { _busy = true; SendMessage(new PipeMessage(MessageType.Init, new Dictionary <string, object> { { "error", PipeErrorCode.Success } })); OnClientConnected?.Invoke(this, null); } else { SendMessage(new PipeMessage(MessageType.Init, new Dictionary <string, object> { { "error", PipeErrorCode.PipeBusy } })); } break; case MessageType.TracerError: //TODO: error message OnTracerError?.Invoke(this, new TracerErrorEventArgs( (PipeErrorCode)int.Parse((string)parsedMessage.MessageData["error"]), "")); break; default: OnPipeMessageReceived?.Invoke(this, new PipeMessageEventArgs(parsedMessage)); break; } // Keep reading ListenForMessages(); }); }
/// <summary> /// Handles incomming commands from the remote host. /// </summary> private void HandleCommands() { while (Active) { try { if (!ClientInterface.Connections["Main"].DataAvailable || Pausing) { Thread.Sleep(10); } Command command = ClientInterface.Connections["Main"].Read <Command>(Password); if (command != null) { switch (command.Type) { case CommandType.Authenticate: case CommandType.Authorized: case CommandType.None: case CommandType.Unauthorized: break; case CommandType.ClientAdded: Clients.Add(command.Sender.ID, command.Sender); OnClientConnected?.BeginInvoke(command.Sender, result => { try { OnClientConnected.EndInvoke(result); } catch { } }, null); break; case CommandType.ClientRemoved: Clients.Remove(command.Sender.ID); OnClientDisconnected?.BeginInvoke(command.Sender, result => { try { OnClientDisconnected.EndInvoke(result); } catch { } }, null); break; case CommandType.Close: Disconnect(false); throw new ThreadInterruptedException(); case CommandType.Custom: OnCustomCommand?.BeginInvoke(command, result => { try { OnCustomCommand.EndInvoke(result); } catch { } }, null); break; default: throw new CommandException($"The command type \"{command.Type}\" was not recognized in this context.", command); } } } catch (ThreadInterruptedException) { break; } catch (Exception error) { Debug.WriteLine($"'{error.GetType()}' thrown in thread {Thread.CurrentThread.ManagedThreadId}. Message: {error.Message}"); } } }
public FizzySteamyMirror() { // dispatch the events from the server server.OnConnected += (id) => OnServerConnected?.Invoke(id); server.OnDisconnected += (id) => OnServerDisconnected?.Invoke(id); server.OnReceivedData += (id, data, channel) => OnServerDataReceived?.Invoke(id, new ArraySegment <byte>(data), channel); server.OnReceivedError += (id, exception) => OnServerError?.Invoke(id, exception); // dispatch events from the client client.OnConnected += () => OnClientConnected?.Invoke(); client.OnDisconnected += () => OnClientDisconnected?.Invoke(); client.OnReceivedData += (data, channel) => OnClientDataReceived?.Invoke(new ArraySegment <byte>(data), channel); client.OnReceivedError += (exception) => OnClientError?.Invoke(exception); Debug.Log("FizzySteamyMirror initialized!"); }
private void LobbyManager_OnMemberConnect(long lobbyId, long userId) { if (ServerActive()) { clients.Add(userId, currentMemberId); OnServerConnected?.Invoke(currentMemberId); currentMemberId++; } else { if (userId == userManager.GetCurrentUser().Id) { OnClientConnected?.Invoke(); } } }
public virtual void ClientConnected(RemoteClient client) { var clientAdapter = new NetcodeIORemoteClientAdapter(client, this); var clientsWithIP = MatchAllRemote(clientAdapter); if (clientsWithIP.Any()) { foreach (var existingClient in clientsWithIP) { existingClient.Disconnect(); } } Clients.AddOrUpdate(clientAdapter, DateTime.Now.Ticks, (x, y) => { return(DateTime.Now.Ticks); }); OnClientConnected?.Invoke(clientAdapter); }