/// <summary>
        /// Accepting the incoming connections and stroing them
        /// </summary>
        /// <param name="ar">The async result</param>

        private void AcceptCallback(IAsyncResult ar)
        {
            try
            {
                Socket      newClient = serverSocket.EndAccept(ar); //The connected client
                MessageData md        = new MessageData()           //Define the ar state object
                {
                    bytes  = new byte[recvBufferSize],
                    sender = newClient
                };

                string friendlyName = "Client" + clientList.Count.ToString();                                               //Client name

                Invoke(() => ClientJoined?.Invoke(friendlyName));                                                           //Call the client joined event

                clientList.Add(newClient);                                                                                  //Add to the client list

                newClient.BeginReceive(md.bytes, 0, recvBufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), md); //begin reading from the stream

                Console.WriteLine("New client connected");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to accept client\r\nError: " + ex.Message);
            }

            serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null); //Restart accepting clients
        }
示例#2
0
 private void DispatchClientConnected(ClientJoined clientJoined)
 {
     if (clientJoined == null)
     {
         return;
     }
     _clients.Add(clientJoined.client_id);
     _eventHandler.OnClientConnected(clientJoined);
 }
        public async Task OnMasterGotClientConnectionAsync(ClientJoined message)
        {
            Debug.Log($"Client connected: {message.client_id}");
            _clients.Add(message.client_id);
            await NetworkConnection.Execute <DemoRpcSetClientState, DemoRpcSetClientStateResponse>(new DemoRpcSetClientState()
            {
                state = DemoRpcClientState.AllowInput
            }, message.client_id);

            await NetworkConnection.Execute <DemoRpcMessage, DemoRpcMessageResponse>(new DemoRpcMessage()
            {
                message = "Welcome to server!"
            }, message.client_id);
        }
示例#4
0
        /// <summary>
        /// Client connected. Establish SSL, do handshake and validate client before accepting it.
        /// </summary>
        /// <param name="r"></param>
        void ClientAccepted(IAsyncResult r)
        {
            // Continue listening
            try
            {
                listener.BeginAcceptTcpClient(ClientAccepted, null);
            }
            catch (Exception ex)
            {
                if (IsListening)
                {
                    Logger.Log($"Failed to continue listening... " + ex.GetDetailedMessage(), Logger.LogSeverity.Debug);
                }
                return;
            }

            // Start accepting client
            var client = listener.EndAcceptTcpClient(r);

            Logger.Log($"Client connecting from {client.Client.RemoteEndPoint}...", Logger.LogSeverity.Debug);

            if (plugins?.Invoke(p => p.OnClientConnecting(client), true) == false)
            {
                // reject client
                Logger.Log("Client rejected by plugin.", Logger.LogSeverity.Debug);
                client.ProperlyClose();
                return;
            }

            // Create client object
            var wc = new WorkerClient(client);

            // Start handshake
            try
            {
                var stream = client.GetStream();

                Logger.Log($"Establishing secure connection to {client.Client.RemoteEndPoint}...", Logger.LogSeverity.Debug);
                // setup SSL here
                var sslstream = SecurityUtils.ServerEstablishSSL(stream, certificate);

                wc.MesssageHandler = new NetworkMessageHandler <NetworkMessage>(sslstream, m => ClientMessageReceived(wc, m));
                wc.MesssageHandler.ExceptionThrown += (a, b) =>
                {
                    wc.MesssageHandler.Dispose();

                    if (wc.Online)
                    {
                        wc.Online = false;
                        ClientLeft?.Invoke(wc, null);

                        Logger.Log($"Client disconnected from {wc.RemoteEndpoint}! ({wc.Id})");

                        // ignore certain common errors
                        if (!IgnoreError(b))
                        {
                            Logger.Log(b.GetDetailedMessage(), Logger.LogSeverity.Debug);
                        }
                    }
                };

                Logger.Log($"Validating {client.Client.RemoteEndPoint}...", Logger.LogSeverity.Debug);

                wc.Id = SecurityUtils.DoHandshake(wc.MesssageHandler, passwordHash, false, null,
                                                  id => Clients.Count(x => x.Id == id) > 0,
                                                  id =>
                {
                    var c = Clients.Where(x => x.Id == id).FirstOrDefault();
                    if (c == null)
                    {
                        return(false);               // generate new Id if client doesn't exist
                    }
                    if (c.Online == true)
                    {
                        return(false);                      // worker already online with this Id, generate new Id
                    }
                    // worker with this Id is offline, assume this is that worker
                    return(true);
                });

                wc.HandshakeCompleted = true;
            }
            catch (Exception ex)
            {
                Logger.Log($"Rejected client from {wc.RemoteEndpoint}. " + ex.Message, Logger.LogSeverity.Warning);
                Logger.Log(ex.GetDetailedMessage(), Logger.LogSeverity.Debug);

                try
                {
                    wc.MesssageHandler.SendMessage(new NetworkMessage(NetworkMessageType.Reject));
                }
                catch { }

                client.ProperlyClose();
                return;
            }

            wc.Online        = true;
            wc.LastConnected = DateTime.Now;

            // try get existing client
            var ewc = Clients.Where(x => x.Id == wc.Id).FirstOrDefault();

            // Accept valid client
            Logger.Log($"Accepted {(ewc == null ? "new" : "existing")} client from {client.Client.RemoteEndPoint}. ({wc.Id})");
            lock (Clients)
            {
                // if client doesn't exist yet, add it - otherwise replace existing client
                if (ewc == null)
                {
                    Clients.Add(wc);
                }
                else
                {
                    var index = Clients.IndexOf(ewc);

                    Clients[index] = wc;
                }
            }

            plugins?.Invoke(p => p.OnClientConnect(wc.Client, wc.Id));

            // send configuration
            wc.MesssageHandler.SendMessage(new NetworkMessage(NetworkMessageType.ConfigUpdate, WorkerConfig));

            // send client limit
            wc.MesssageHandler.SendMessage(new NetworkMessage(
                                               NetworkMessageType.WorkLimitUpdate, config.ClientWorkLimit));

            ClientJoined?.Invoke(wc, ewc != null);
        }
 public void OnClientConnected(ClientJoined message)
 {
     _master.OnMasterGotClientConnectionAsync(message).Promise().Then(() => { }, (err) => _manager.Logger.OnError(err)).Dispatch();
 }
示例#6
0
 private void OnClientJoined(RailController client)
 {
     ClientJoined?.Invoke(client);
 }