/// <summary>
        /// Reads all packets and create messages
        /// </summary>
        protected void BaseHeartbeat(double now)
        {
            // discovery
            NetProfiler.BeginSample("_CheckLocalDiscovery");
            m_discovery.Heartbeat(now);
            NetProfiler.EndSample();

            // Send queued system messages
            NetProfiler.BeginSample("_SendQueuedSystemMessages");
            SendQueuedSystemMessages();
            NetProfiler.EndSample();

            // Send out-of-band messages
            NetProfiler.BeginSample("_SendQueuedUnconnectedMessages");
            SendQueuedOutOfBandMessages();
            NetProfiler.EndSample();

//#if DEBUG
            NetProfiler.BeginSample("_SendLagSimulatedPackets");
            SendDelayedPackets(now);
            NetProfiler.EndSample();
//#endif

            // TODO: move this up in order
            NetProfiler.BeginSample("_ReceivePackets");
            ReceivePackets(now);
            NetProfiler.EndSample();
        }
예제 #2
0
        /// <summary>
        /// Reads all packets and create messages
        /// </summary>
        protected void BaseHeartbeat(double now)
        {
            if (!m_isBound)
            {
                return;
            }

            // discovery
            m_discovery.Heartbeat(now);

            // hole punching
            if (m_holePunches != null)
            {
                if (now > m_lastHolePunch + NetConstants.HolePunchingFrequency)
                {
                    if (m_holePunches.Count <= 0)
                    {
                        m_holePunches = null;
                    }
                    else
                    {
                        IPEndPoint dest = m_holePunches[0];
                        m_holePunches.RemoveAt(0);
                        NotifyApplication(NetMessageType.DebugMessage, "Sending hole punch to " + dest, null);
                        NetConnection.SendPing(this, dest, now);
                        if (m_holePunches.Count < 1)
                        {
                            m_holePunches = null;
                        }
                        m_lastHolePunch = now;
                    }
                }
            }

            // Send queued system messages
            if (m_susmQueue.Count > 0)
            {
                lock (m_susmQueue)
                {
                    while (m_susmQueue.Count > 0)
                    {
                        SUSystemMessage su = m_susmQueue.Dequeue();
                        SendSingleUnreliableSystemMessage(su.Type, su.Data, su.Destination, su.UseBroadcast);
                    }
                }
            }

            // Send out-of-band messages
            if (m_unsentOutOfBandMessages.Count > 0)
            {
                lock (m_unsentOutOfBandMessages)
                {
                    while (m_unsentOutOfBandMessages.Count > 0)
                    {
                        NetBuffer  buf = m_unsentOutOfBandMessages.Dequeue();
                        IPEndPoint ep  = m_unsentOutOfBandRecipients.Dequeue();
                        DoSendOutOfBandMessage(buf, ep);
                    }
                }
            }

            try
            {
#if DEBUG
                SendDelayedPackets(now);
#endif

                while (true)
                {
                    if (m_socket == null || m_socket.Available < 1)
                    {
                        return;
                    }
                    m_receiveBuffer.Reset();

                    int bytesReceived = 0;
                    try
                    {
                        bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer.Data, 0, m_receiveBuffer.Data.Length, SocketFlags.None, ref m_senderRemote);
                    }
                    catch (SocketException)
                    {
                        // no good response to this yet
                        return;
                    }
                    if (bytesReceived < 1)
                    {
                        return;
                    }
                    if (bytesReceived > 0)
                    {
                        m_statistics.CountPacketReceived(bytesReceived);
                    }
                    m_receiveBuffer.LengthBits = bytesReceived * 8;

                    //LogVerbose("Read packet: " + bytesReceived + " bytes");

                    IPEndPoint ipsender = (IPEndPoint)m_senderRemote;

                    NetConnection sender = GetConnection(ipsender);
                    if (sender != null)
                    {
                        sender.m_statistics.CountPacketReceived(bytesReceived, now);
                    }

                    // create messages from packet
                    while (m_receiveBuffer.Position < m_receiveBuffer.LengthBits)
                    {
                        int beginPosition = m_receiveBuffer.Position;

                        // read message header
                        IncomingNetMessage msg = CreateIncomingMessage();
                        msg.m_sender = sender;
                        msg.ReadFrom(m_receiveBuffer, ipsender);

                        // statistics
                        if (sender != null)
                        {
                            sender.m_statistics.CountMessageReceived(msg.m_type, msg.m_sequenceChannel, (m_receiveBuffer.Position - beginPosition) / 8, now);
                        }

                        // handle message
                        HandleReceivedMessage(msg, ipsender);
                    }
                }
            }
            catch (SocketException sex)
            {
                if (sex.ErrorCode == 10054)
                {
                    // forcibly closed; but m_senderRemote is unreliable, we can't trust it!
                    //NetConnection conn = GetConnection((IPEndPoint)m_senderRemote);
                    //HandleConnectionForciblyClosed(conn, sex);
                    return;
                }
            }
            catch (Exception ex)
            {
                throw new NetException("ReadPacket() exception", ex);
            }
        }