Exemple #1
0
        internal void ExecuteDisconnect(string reason, bool sendByeMessage)
        {
            m_peer.VerifyNetworkThread();

            // m_peer.LogDebug("Executing disconnect");

            // clear send queues
            for (int i = 0; i < m_sendChannels.Length; i++)
            {
                NetSenderChannelBase channel = m_sendChannels[i];
                if (channel != null)
                {
                    channel.Reset();
                }
            }

            if (sendByeMessage)
            {
                SendDisconnect(reason, true);
            }

            SetStatus(NetConnectionStatus.Disconnected, reason);

            // in case we're still in handshake
            lock (m_peer.m_handshakes)
                m_peer.m_handshakes.Remove(m_remoteEndpoint);

            m_disconnectRequested = false;
            m_connectRequested    = false;
            m_handshakeAttempts   = 0;
        }
        // received a library message while Connected
        internal void ReceivedLibraryMessage(NetMessageType tp, int ptr, int payloadLength)
        {
            m_peer.VerifyNetworkThread();

            float now = (float)NetTime.Now;

            switch (tp)
            {
            case NetMessageType.Disconnect:
                NetIncomingMessage msg = m_peer.SetupReadHelperMessage(ptr, payloadLength);
                ExecuteDisconnect(msg.ReadString(), false);
                break;

            case NetMessageType.Acknowledge:
                for (int i = 0; i < payloadLength; i += 3)
                {
                    NetMessageType acktp = (NetMessageType)m_peer.m_receiveBuffer[ptr++];                             // netmessagetype
                    int            seqNr = m_peer.m_receiveBuffer[ptr++];
                    seqNr |= (m_peer.m_receiveBuffer[ptr++] << 8);

                    NetSenderChannelBase chan = m_sendChannels[(int)acktp - 1];
                    if (chan == null)
                    {
                        chan = CreateSenderChannel(acktp);
                    }

                    //m_peer.LogVerbose("Received ack for " + acktp + "#" + seqNr);

                    chan.ReceiveAcknowledge(now, seqNr);
                }
                break;

            case NetMessageType.Ping:
                int pingNr = m_peer.m_receiveBuffer[ptr++];
                SendPong(pingNr);
                break;

            case NetMessageType.Pong:
                NetIncomingMessage pmsg = m_peer.SetupReadHelperMessage(ptr, payloadLength);
                int   pongNr            = pmsg.ReadByte();
                float remoteSendTime    = pmsg.ReadSingle();
                ReceivedPong(now, pongNr, remoteSendTime);
                break;

            case NetMessageType.ExpandMTURequest:
                SendMTUSuccess(payloadLength);
                break;

            case NetMessageType.ExpandMTUSuccess:
                NetIncomingMessage emsg = m_peer.SetupReadHelperMessage(ptr, payloadLength);
                int size = emsg.ReadInt32();
                HandleExpandMTUSuccess(now, size);
                break;

            default:
                m_peer.LogWarning("Connection received unhandled library message: " + tp);
                break;
            }
        }
        // called by SendMessage() and NetPeer.SendMessage; ie. may be user thread
        internal NetSendResult EnqueueMessage(NetOutgoingMessage msg, NetDeliveryMethod method, int sequenceChannel)
        {
            NetMessageType tp = (NetMessageType)((int)method + sequenceChannel);

            msg.m_messageType = tp;

            // TODO: do we need to make this more thread safe?
            int channelSlot           = (int)method - 1 + sequenceChannel;
            NetSenderChannelBase chan = m_sendChannels[channelSlot];

            if (chan == null)
            {
                chan = CreateSenderChannel(tp);
            }

            if (msg.GetEncodedSize() > m_currentMTU)
            {
                throw new NetException("Message too large! Fragmentation failure?");
            }

            return(chan.Enqueue(msg));
        }