Beispiel #1
0
        /// <summary>
        /// Attempts to connects to the server.
        /// </summary>
        /// <param name="host">The server address.</param>
        /// <param name="port">The server port.</param>
        /// <param name="approvalMessage">The initial message to send to the server when making the connection. This can
        /// be utilized by the server to provide additional information for determining whether or not to accept the connection.
        /// Or, can be null to send nothing.</param>
        /// <returns>
        /// True if the connection attempt was successfully started. Does not mean that the connection was established, but
        /// just that it can be attempted. Will return false if a connection is already established or being established.
        /// </returns>
        public bool Connect(string host, int port, BitStream approvalMessage = null)
        {
            if (_local.ConnectionsCount > 0)
            {
                return(false);
            }

            NetConnection conn;

            if (approvalMessage != null && approvalMessage.LengthBits > 0)
            {
                // Connect with approval message
                var netOutMsg = SocketHelper.GetNetOutgoingMessage(_local, approvalMessage.LengthBytes);
                approvalMessage.CopyTo(netOutMsg);

                conn = _local.Connect(host, port, netOutMsg);
            }
            else
            {
                // Connect without approval message
                conn = _local.Connect(host, port);
            }

            // Check if connection successful
            if (conn == null)
            {
                Debug.Fail("conn is null. Why?");
                return(false);
            }

            // Store the remote connection as an IPSocket
            _remote = IPSocket.Create(conn);

            return(true);
        }
        /// <summary>
        /// Handles processing of the underlying connection(s) and promoting data to the upper layer to be handled
        /// by the application. Should be called once per frame.
        /// </summary>
        public void Heartbeat()
        {
            const string debugMsgFormat = "Debug message from `{0}` on `{1}`: {2}";

            NetIncomingMessage incMsg;

            while ((incMsg = _local.ReadMessage()) != null)
            {
                IIPSocket ipSocket;

                switch (incMsg.MessageType)
                {
                case NetIncomingMessageType.DebugMessage:
                case NetIncomingMessageType.VerboseDebugMessage:
                    if (log.IsDebugEnabled)
                    {
                        var debugMsg = incMsg.ReadString();
                        log.DebugFormat(debugMsgFormat, incMsg.SenderConnection, this, debugMsg);
                    }
                    break;

                case NetIncomingMessageType.WarningMessage:
                    if (log.IsWarnEnabled)
                    {
                        var debugMsg = incMsg.ReadString();
                        log.WarnFormat(debugMsgFormat, incMsg.SenderConnection, this, debugMsg);
                    }
                    break;

                case NetIncomingMessageType.ErrorMessage:
                    if (log.IsErrorEnabled)
                    {
                        var debugMsg = incMsg.ReadString();
                        log.ErrorFormat(debugMsgFormat, incMsg.SenderConnection, this, debugMsg);
                    }
                    break;

                case NetIncomingMessageType.ConnectionApproval:

                    // Make sure that the IIPSocket has been created
                    ipSocket = IPSocket.Create(incMsg.SenderConnection);
                    Debug.Assert(ipSocket != null);

                    // Copy the received data into a BitStream before passing it up
                    _receiveBitStream.Reset();
                    _receiveBitStream.Write(incMsg);
                    _receiveBitStream.PositionBits = 0;

                    // Ask the acception handler method if this connection will be accepted
                    var rejectMessage = AcceptConnect(ipSocket.IP, ipSocket.Port, _receiveBitStream);

                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Received connection request from `{0}`. Accepted? {1}.", ipSocket,
                                        string.IsNullOrEmpty(rejectMessage));
                    }

                    // Approve or deny the connection accordingly
                    if (string.IsNullOrEmpty(rejectMessage))
                    {
                        incMsg.SenderConnection.Approve();
                    }
                    else
                    {
                        incMsg.SenderConnection.Deny(rejectMessage);
                    }

                    break;

                case NetIncomingMessageType.StatusChanged:

                    // Make sure that the IIPSocket has been created
                    ipSocket = IPSocket.Create(incMsg.SenderConnection);
                    Debug.Assert(ipSocket != null);

                    // Read the status and reason
                    var status = (NetConnectionStatus)incMsg.ReadByte();
                    var reason = incMsg.ReadString();

                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Socket `{0}` status changed to `{1}`. Reason: {2}", ipSocket, status, reason);
                    }

                    // Forward to the handler
                    OnReceiveStatusChanged(ipSocket, status, reason);

                    break;

                case NetIncomingMessageType.Data:

                    // Get the IIPSocket for the connection (it definitely should be created by this point)
                    ipSocket = (IIPSocket)incMsg.SenderConnection.Tag;
                    Debug.Assert(ipSocket != null);

                    // Copy the received data into a BitStream before passing it up
                    _receiveBitStream.Reset();
                    _receiveBitStream.Write(incMsg);
                    _receiveBitStream.PositionBits = 0;

                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Received {0} bits from {1}.", incMsg.LengthBits, ipSocket);
                    }

                    // Forward the data to the data handler
                    OnReceiveData(ipSocket, _receiveBitStream);

                    break;
                }

                _local.Recycle(incMsg);
            }
        }