/// <summary> /// Handle a discovery request /// </summary> internal void HandleRequest(IncomingNetMessage message, NetworkEndPoint senderEndpoint) { ushort number; if (!VerifyIdentifiers(message, senderEndpoint, out number)) { return; // bad app ident or self discovery } NetBuffer buf = m_netBase.CreateBuffer(2); buf.Write(number); m_netBase.LogWrite("Sending discovery response to " + senderEndpoint + " request " + number); // send discovery response m_netBase.SendSingleUnreliableSystemMessage( NetSystemType.DiscoveryResponse, buf, senderEndpoint, null ); m_netBase.RecycleBuffer(buf); }
// TODO: Use this with TRUE isLibraryThread for internal sendings (acks etc) internal void SendMessage(NetBuffer data, NetChannel channel, NetBuffer receiptData, bool isLibraryThread) { if (m_status != NetConnectionStatus.Connected) { throw new NetException("Status must be Connected to send messages"); } if (data.LengthBytes > m_owner.m_config.m_maximumTransmissionUnit) { // // Fragmented message // int dataLen = data.LengthBytes; int chunkSize = m_owner.m_config.m_maximumTransmissionUnit - 10; // header int numFragments = dataLen / chunkSize; if (chunkSize * numFragments < dataLen) { numFragments++; } ushort fragId = m_nextSendFragmentId++; for (int i = 0; i < numFragments; i++) { OutgoingNetMessage fmsg = m_owner.CreateOutgoingMessage(); fmsg.m_type = NetMessageLibraryType.UserFragmented; fmsg.m_msgType = NetMessageType.Data; NetBuffer fragBuf = m_owner.CreateBuffer(); fragBuf.Write(fragId); fragBuf.WriteVariableUInt32((uint)i); fragBuf.WriteVariableUInt32((uint)numFragments); if (i < numFragments - 1) { // normal fragment fragBuf.Write(data.Data, i * chunkSize, chunkSize); } else { // last fragment int bitsInLast = data.LengthBits - (chunkSize * (numFragments - 1) * 8); int bytesInLast = dataLen - (chunkSize * (numFragments - 1)); fragBuf.Write(data.Data, i * chunkSize, bytesInLast); // add receipt only to last message fmsg.m_receiptData = receiptData; } fmsg.m_data = fragBuf; fmsg.m_data.m_refCount = 1; // since it's just been created fmsg.m_numSent = 0; fmsg.m_nextResend = double.MaxValue; fmsg.m_sequenceChannel = channel; fmsg.m_sequenceNumber = -1; if (isLibraryThread) { m_unsentMessages.Enqueue(fmsg); } else { lock (m_lockedUnsentMessages) m_lockedUnsentMessages.Enqueue(fmsg); } } // TODO: recycle the original, unfragmented data return; } // // Normal, unfragmented, message // OutgoingNetMessage msg = m_owner.CreateOutgoingMessage(); msg.m_msgType = NetMessageType.Data; msg.m_type = NetMessageLibraryType.User; msg.m_data = data; msg.m_data.m_refCount++; // it could have been sent earlier also msg.m_numSent = 0; msg.m_nextResend = double.MaxValue; msg.m_sequenceChannel = channel; msg.m_sequenceNumber = -1; msg.m_receiptData = receiptData; if (isLibraryThread) { m_unsentMessages.Enqueue(msg); } else { lock (m_lockedUnsentMessages) m_lockedUnsentMessages.Enqueue(msg); } }