示例#1
0
        /// <summary>
        /// Creates an <see cref="IPSocket"/> for a <see cref="NetConnection"/> and stores it in the
        /// <see cref="NetConnection.Tag"/> property. If the <see cref="IPSocket"/> for the given <see cref="NetConnection"/>
        /// already exists, a new one will not be created and the existing one will be returned.
        /// </summary>
        /// <param name="conn">The <see cref="NetConnection"/> to create the <see cref="IPSocket"/> for.</param>
        /// <returns>The <see cref="IPSocket"/> for the <paramref name="conn"/>.</returns>
        public static IPSocket Create(NetConnection conn)
        {
            // Check for an IPSocket already attached
            var ret = conn.Tag as IPSocket;
            if (ret != null)
                return ret;

            // Create the IPSocket instance and attach it to the tag
            ret = new IPSocket(conn);
            conn.Tag = ret;

            return ret;
        }
示例#2
0
文件: IPSocket.cs 项目: wtfcolt/game
        /// <summary>
        /// Creates an <see cref="IPSocket"/> for a <see cref="NetConnection"/> and stores it in the
        /// <see cref="NetConnection.Tag"/> property. If the <see cref="IPSocket"/> for the given <see cref="NetConnection"/>
        /// already exists, a new one will not be created and the existing one will be returned.
        /// </summary>
        /// <param name="conn">The <see cref="NetConnection"/> to create the <see cref="IPSocket"/> for.</param>
        /// <returns>The <see cref="IPSocket"/> for the <paramref name="conn"/>.</returns>
        public static IPSocket Create(NetConnection conn)
        {
            // Check for an IPSocket already attached
            var ret = conn.Tag as IPSocket;

            if (ret != null)
            {
                return(ret);
            }

            // Create the IPSocket instance and attach it to the tag
            ret      = new IPSocket(conn);
            conn.Tag = ret;

            return(ret);
        }
        /// <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);
            }
        }