/// <summary>
        ///
        /// </summary>
        public void Loop()
        {
            try
            {
                // This is checked each cycle
                while (this.IsRunning)
                {
                    _client.MessageReceivedEvent.WaitOne(1000);
                    NetIncomingMessage msg = _client.ReadMessage();

                    // No message received, please relieve CPU
                    if (msg == null)
                    {
                        continue;
                    }

                    switch (msg.MessageType)
                    {
                    case NetIncomingMessageType.Data:
                        if (msg.SenderConnection.Tag is Connection)
                        {
                            ((Connection)msg.SenderConnection.Tag).IncomingMessage(msg);
                        }
                        else
                        {
                            NetLobby.IncomingMessage(msg);
                        }
                        break;

                    case NetIncomingMessageType.StatusChanged:
                        NetConnectionStatus statusByte = (NetConnectionStatus)msg.ReadByte();
                        switch (statusByte)
                        {
                        case NetConnectionStatus.Disconnecting:
                            break;

                        // When disconnect is called and processed
                        case NetConnectionStatus.Disconnected:

                            // If already connection established, destroy resources
                            if (msg.SenderConnection.Tag is Connection &&
                                !((Connection)msg.SenderConnection.Tag).IsDisposed)
                            {
                                ((Connection)msg.SenderConnection.Tag).Dispose();
                            }

                            // Received a reason for disconnecting? (e.a. Handshake Fail)
                            String finalReason = Encoding.UTF8.GetString(msg.ReadBytes((Int32)msg.ReadVariableUInt32()));

                            // Some exceptions that should be catched but even so
                            if (finalReason.StartsWith("Handshake data validation failed"))
                            {
                                SetStep(AuthenticationStatus.NoServerConnection);
                                OnAuthenticationFailed.Invoke("Could not connect");
                            }
                            else if (finalReason.StartsWith("Failed to establish"))
                            {
                                SetStep(AuthenticationStatus.NoServerConnection);
                                OnAuthenticationTimeout.Invoke("Could not connect");
                            }

                            Disconnect("");
                            break;

                        case NetConnectionStatus.Connected:
                            SetStep(AuthenticationStatus.ServerConnection);

                            var username = _username;
                            var password = _password;

                            // Connected so lets start authenticating
                            Authenticate(_client.ServerConnection, _username, _password);
                            break;
                        }
                        break;
                    }
                }

                Disconnect("");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Client message loop
        /// </summary>
        private void ClientLoop()
        {
            NetIncomingMessage msg;

            while (this.IsRunning)
            {
                _server.MessageReceivedEvent.WaitOne(1000);
                msg = _server.ReadMessage();

                // If this second no messages accepted, releave CPU
                if (msg == null)
                {
                    continue;
                }

                try
                {
                    switch (msg.MessageType)
                    {
                    // MESSAGETYPE: DATA
                    // The main message type in networking is the data type. When the connection is not linked, the
                    // data is the verification data of the handshake and will be processed accordingly. If not,
                    // the message is passed onto the Connection and processed by their respective protocol.
                    case NetIncomingMessageType.Data:

                        var connection = msg.SenderConnection.Tag as Connection;
                        if (connection != null)
                        {
                            // Client was authenticated so just process the message
                            connection.IncomingMessage(msg);
                        }
                        else
                        {
                            // Client is not yet authenticate so handle that. In my case we directly expect
                            // authentication, but you can write your own handling code. The following code
                            // handles just that.
                            var handshake = NetLobby.IncomingMessage(msg);

                            switch (handshake)
                            {
                            case Handshake.Contents.Succes:
                                Connection new_connection = new Connection(_server, msg.SenderConnection, (msg.SenderConnection.Tag as Handshake).CreateEncryption());
                                OnConnected.Invoke(new_connection.NodeId, new_connection.Username);
                                break;

                            case Handshake.Contents.Error:
                            case Handshake.Contents.Denied:
                                msg.SenderConnection.Disconnect("Error occured during handshake.");
                                break;

                            case Handshake.Contents.Expired:
                                msg.SenderConnection.Disconnect("Handshake expired.");
                                break;
                            }
                        }

                        break;

                    // MESSAGETYPE: CONNECTION APPROVAL
                    // The ConnectionApproval message type is seen when a node yields the peer#connect function. When
                    // the RemoteEndpoint specified is reached, a loose connection is made. It's up to the other end,
                    // the one that is connected too, to deny or approve the connection.
                    case NetIncomingMessageType.ConnectionApproval:

                        // Here you can add approval code to the public section of the server

                        msg.SenderConnection.Approve();

                        break;

                    // MESSAGETYPE: STATUS CHANGED
                    // Internal type that is triggered when a connection is initiated, responded too, connecting,
                    // disconnecting, connected or disconnected. Upon a connection, we might have received some
                    // RemoteHailData. This is part of the SRPP protocol and is proccesed accordingly. When
                    // disconnecting, the Connection is disposed, internal connection is disconnected and all is
                    // logged.
                    case NetIncomingMessageType.StatusChanged:

                        NetConnectionStatus statusByte = (NetConnectionStatus)msg.ReadByte();

                        switch (statusByte)
                        {
                        case NetConnectionStatus.Disconnecting:
                            break;

                        case NetConnectionStatus.Disconnected:
                            // If already connection established, destroy resources
                            var disconnected_connection = msg.SenderConnection.Tag as Connection;
                            if (disconnected_connection != null)
                            {
                                OnDisconnected.Invoke(disconnected_connection.NodeId, disconnected_connection.Username);

                                if (!disconnected_connection.IsDisposed)
                                {
                                    disconnected_connection.Dispose();
                                }
                            }

                            String finalReason = Encoding.UTF8.GetString(msg.ReadBytes((Int32)msg.ReadVariableUInt32()));
                            // Do something with the message if you want like logging: Received a reason for disconnecting...
                            break;

                        case NetConnectionStatus.Connected:
                            break;

                        default:
                            String statusChange = Encoding.UTF8.GetString(msg.ReadBytes((Int32)msg.ReadVariableUInt32()));
                            // You can log/debug status messages here
                            break;
                        }

                        break;

                            #if DEBUG
                    case NetIncomingMessageType.DebugMessage:
                        String debugMessage = Encoding.UTF8.GetString(msg.ReadBytes((Int32)msg.ReadVariableUInt32()));
                        // log
                        break;
                            #endif

                    case NetIncomingMessageType.WarningMessage:
                        String warningMessage = Encoding.UTF8.GetString(msg.ReadBytes((Int32)msg.ReadVariableUInt32()));
                        // log;
                        break;

                    case NetIncomingMessageType.ErrorMessage:
                        String errorMessage = Encoding.UTF8.GetString(msg.ReadBytes((Int32)msg.ReadVariableUInt32()));
                        // log
                        break;

                    default:
                        throw new NetException("MessageType: " + msg.MessageType + " is not supported.");
                    }

                    // Recycle please
                    _server.Recycle(msg);
                }
                catch (Exception e)
                {
                    try
                    {
                        // Disconnect client on error
                        msg.SenderConnection.Disconnect("No tolerance: exception " + e.Message);
                    }
                    catch (Exception) { }
                }
            }

            // Early shutdown
            _server.Shutdown("Server shutting down");

            Console.WriteLine("Client Service is Stopping at " + NetTime.ToReadable(NetTime.Now));
            _server.Shutdown("Final shutdown");
        }