private void SendQueuedSystemMessages() { if (m_susmQueue.Count > 0) { while (m_susmQueue.Count > 0) { SUSystemMessage su = m_susmQueue.Dequeue(); SendSingleUnreliableSystemMessage(su.Type, su.Data, su.Destination, null); } } }
/// <summary> /// Thread-safe SendSingleUnreliableSystemMessage() /// </summary> internal void QueueSingleUnreliableSystemMessage( NetSystemType tp, NetBuffer data, NetworkEndPoint remoteEP, bool useBroadcast) { var susm = new SUSystemMessage(); susm.Type = tp; susm.Data = data; susm.Destination = remoteEP; susm.UseBroadcast = useBroadcast; m_susmQueue.Enqueue(susm); }
/// <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); } }
/// <summary> /// Thread-safe SendSingleUnreliableSystemMessage() /// </summary> internal void QueueSingleUnreliableSystemMessage( NetSystemType tp, NetBuffer data, IPEndPoint remoteEP, bool useBroadcast) { SUSystemMessage susm = new SUSystemMessage(); susm.Type = tp; susm.Data = data; susm.Destination = remoteEP; susm.UseBroadcast = useBroadcast; lock (m_susmQueue) m_susmQueue.Enqueue(susm); }