protected void processPacket(ushort seq, byte[] packetData, int packetLen) { using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(packetData)) { while (byteArrayReaderWriter.ReadPosition < packetLen) { ushort num = byteArrayReaderWriter.ReadUInt16(); ushort num2 = readVariableLengthUShort(byteArrayReaderWriter); if (num2 != 0) { if (!receiveBuffer.Exists(num)) { BufferedPacket bufferedPacket = receiveBuffer.Insert(num); bufferedPacket.buffer.SetSize(num2); byteArrayReaderWriter.ReadBytesIntoBuffer(bufferedPacket.buffer.InternalBuffer, num2); } else { byteArrayReaderWriter.SeekRead(byteArrayReaderWriter.ReadPosition + (int)num2); } while (receiveBuffer.Exists(nextReceive)) { BufferedPacket bufferedPacket2 = receiveBuffer.Find(nextReceive); ReceiveCallback(ChannelID, bufferedPacket2.buffer.InternalBuffer, bufferedPacket2.buffer.Length); receiveBuffer.Remove(nextReceive); nextReceive++; } } } } }
// process incoming packets and turn them into messages protected void processPacket(ushort seq, byte[] packetData, int packetLen) { using (var reader = ByteArrayReaderWriter.Get(packetData)) { while (reader.ReadPosition < packetLen) { // get message bytes and send to receive callback ushort messageID = reader.ReadUInt16(); ushort messageLength = readVariableLengthUShort(reader); if (messageLength == 0) { continue; } if (!receiveBuffer.Exists(messageID)) { var receivedMessage = receiveBuffer.Insert(messageID); receivedMessage.buffer.SetSize(messageLength); reader.ReadBytesIntoBuffer(receivedMessage.buffer.InternalBuffer, messageLength); } else { reader.SeekRead(reader.ReadPosition + messageLength); } // keep returning the next message we're expecting as long as it's available while (receiveBuffer.Exists(nextReceive)) { var msg = receiveBuffer.Find(nextReceive); ReceiveCallback(msg.buffer.InternalBuffer, msg.buffer.Length); receiveBuffer.Remove(nextReceive); nextReceive++; } } } }
public UnreliableMessageChannel() { receiveBuffer = new SequenceBuffer <ReceivedPacketData>(256); config = ReliableConfig.DefaultConfig(); config.TransmitPacketCallback = delegate(byte[] buffer, int size) { TransmitCallback(buffer, size); }; config.ProcessPacketCallback = delegate(ushort seq, byte[] buffer, int size) { if (!receiveBuffer.Exists(seq)) { receiveBuffer.Insert(seq); ReceiveCallback(ChannelID, buffer, size); } }; packetController = new ReliablePacketController(config, DateTime.Now.GetTotalSeconds()); }
public override void Update(double newTime) { double dt = newTime - time; time = newTime; this.packetController.Update(time); // see if we can pop messages off of the message queue and put them on the send queue if (messageQueue.Count > 0) { int sendBufferSize = 0; for (ushort seq = oldestUnacked; PacketIO.SequenceLessThan(seq, this.sequence); seq++) { if (sendBuffer.Exists(seq)) { sendBufferSize++; } } if (sendBufferSize < sendBuffer.Size) { var message = messageQueue.Dequeue(); SendMessage(message.InternalBuffer, 0, message.Length); ObjPool <ByteBuffer> .Return(message); } } // update congestion mode { // conditions are bad if round-trip-time exceeds 250ms bool conditionsBad = (this.packetController.RTT >= 250f); // if conditions are bad, immediately enable congestion control and reset the congestion timer if (conditionsBad) { if (this.congestionControl == false) { // if we're within 10 seconds of the last time we switched, double the threshold interval if (time - lastCongestionSwitchTime < 10.0) { congestionDisableInterval = Math.Min(congestionDisableInterval * 2, 60.0); } lastCongestionSwitchTime = time; } this.congestionControl = true; this.congestionDisableTimer = 0.0; } // if we're in bad mode, and conditions are good, update the timer and see if we can disable congestion control if (this.congestionControl && !conditionsBad) { this.congestionDisableTimer += dt; if (this.congestionDisableTimer >= this.congestionDisableInterval) { this.congestionControl = false; lastCongestionSwitchTime = time; congestionDisableTimer = 0.0; } } // as long as conditions are good, halve the threshold interval every 10 seconds if (this.congestionControl == false) { congestionDisableTimer += dt; if (congestionDisableTimer >= 10.0) { congestionDisableInterval = Math.Max(congestionDisableInterval * 0.5, 5.0); } } } // if we're in congestion control mode, only send packets 10 times per second. // otherwise, send 30 times per second double flushInterval = congestionControl ? 0.1 : 0.033; if (time - lastBufferFlush >= flushInterval) { lastBufferFlush = time; processSendBuffer(); } }
public override void Update(double newTime) { double num = newTime - time; time = newTime; packetController.Update(time); if (messageQueue.Count > 0) { int num2 = 0; ushort num3 = oldestUnacked; while (PacketIO.SequenceLessThan(num3, sequence)) { if (sendBuffer.Exists(num3)) { num2++; } num3 = (ushort)(num3 + 1); } if (num2 < sendBuffer.Size) { ByteBuffer byteBuffer = messageQueue.Dequeue(); SendMessage(byteBuffer.InternalBuffer, byteBuffer.Length); ObjPool <ByteBuffer> .Return(byteBuffer); } } bool flag = packetController.RTT >= 250f; if (flag) { if (!congestionControl) { if (time - lastCongestionSwitchTime < 10.0) { congestionDisableInterval = Math.Min(congestionDisableInterval * 2.0, 60.0); } lastCongestionSwitchTime = time; } congestionControl = true; congestionDisableTimer = 0.0; } if (congestionControl && !flag) { congestionDisableTimer += num; if (congestionDisableTimer >= congestionDisableInterval) { congestionControl = false; lastCongestionSwitchTime = time; congestionDisableTimer = 0.0; } } if (!congestionControl) { congestionDisableTimer += num; if (congestionDisableTimer >= 10.0) { congestionDisableInterval = Math.Max(congestionDisableInterval * 0.5, 5.0); } } double num4 = (!congestionControl) ? 0.033 : 0.1; if (time - lastBufferFlush >= num4) { lastBufferFlush = time; processSendBuffer(); } }