protected void ackPacket(ushort seq) { OutgoingPacketSet outgoingPacketSet = ackBuffer.Find(seq); if (outgoingPacketSet == null) { return; } for (int i = 0; i < outgoingPacketSet.MessageIds.Count; i++) { ushort num = outgoingPacketSet.MessageIds[i]; if (sendBuffer.Exists(num)) { sendBuffer.Find(num).writeLock = true; sendBuffer.Remove(num); } } bool flag = true; ushort num2 = oldestUnacked; while (num2 == sequence || PacketIO.SequenceLessThan(num2, sequence)) { if (sendBuffer.Exists(num2)) { oldestUnacked = num2; flag = false; break; } num2 = (ushort)(num2 + 1); } if (flag) { oldestUnacked = sequence; } }
protected void processSendBuffer() { for (ushort seq = oldestUnacked; PacketIO.SequenceLessThan(seq, this.sequence); seq++) { // never send message ID >= ( oldestUnacked + bufferSize ) if (seq >= (oldestUnacked + 256)) { break; } // for any message that hasn't been sent in the last 0.1 seconds and fits in the available space of our message packer, add it var packet = sendBuffer.Find(seq); if (packet != null) { if (time - packet.time < 0.1) { continue; } bool packetFits = false; if (packet.buffer.Length < config.FragmentThreshold) { packetFits = (messagePacker.Length + packet.buffer.Length) <= (config.FragmentThreshold - Defines.MAX_PACKET_HEADER_BYTES); } else { packetFits = (messagePacker.Length + packet.buffer.Length) <= (config.MaxPacketSize - Defines.FRAGMENT_HEADER_BYTES - Defines.MAX_PACKET_HEADER_BYTES); } // if the packet won't fit, flush the message packer if (!packetFits) { flushMessagePacker(); } packet.time = time; int ptr = messagePacker.Length; messagePacker.SetSize(messagePacker.Length + packet.buffer.Length); messagePacker.BufferCopy(packet.buffer, 0, ptr, packet.buffer.Length); tempList.Add(seq); lastMessageSend = time; } } // if it has been 0.1 seconds since the last time we sent a message, send an empty message if (time - lastMessageSend >= 0.1) { sendAckPacket(); lastMessageSend = time; } // flush any remaining messages in message packer flushMessagePacker(); }
public T Insert(ushort sequence) { if (PacketIO.SequenceLessThan(sequence, (ushort)(this.sequence - numEntries))) { return((T)null); } if (PacketIO.SequenceGreaterThan((ushort)(sequence + 1), this.sequence)) { RemoveEntries(this.sequence, sequence); this.sequence = (ushort)(sequence + 1); } int num = (int)sequence % numEntries; entrySequence[num] = sequence; return(entryData[num]); }
public T Insert(ushort sequence) { if (PacketIO.SequenceLessThan(sequence, (ushort)(this.sequence - numEntries))) { return(null); } if (PacketIO.SequenceGreaterThan((ushort)(sequence + 1), this.sequence)) { RemoveEntries(this.sequence, sequence); this.sequence = (ushort)(sequence + 1); } int index = sequence % numEntries; this.entrySequence[index] = sequence; return(this.entryData[index]); }
public override void SendMessage(byte[] buffer, int bufferPosition, int bufferLength) { int sendBufferSize = 0; for (ushort seq = oldestUnacked; PacketIO.SequenceLessThan(seq, this.sequence); seq++) { if (sendBuffer.Exists(seq)) { sendBufferSize++; } } if (sendBufferSize == sendBuffer.Size) { ByteBuffer tempBuff = ObjPool <ByteBuffer> .Get(); tempBuff.SetSize(bufferLength); tempBuff.BufferCopy(buffer, bufferPosition, 0, bufferLength); messageQueue.Enqueue(tempBuff); return; } ushort sequence = this.sequence++; var packet = sendBuffer.Insert(sequence); packet.time = -1.0; // ensure size for header int varLength = getVariableLengthBytes((ushort)bufferLength); packet.buffer.SetSize(2 + varLength + bufferLength); using (var writer = ByteArrayReaderWriter.Get(packet.buffer.InternalBuffer)) { writer.Write(sequence); writeVariableLengthUShort((ushort)bufferLength, writer); writer.WriteBuffer(buffer, bufferPosition, bufferLength); } // signal that packet is ready to be sent packet.writeLock = false; }
protected void ackPacket(ushort seq) { // first, map seq to message IDs and ack them var outgoingPacket = ackBuffer.Find(seq); if (outgoingPacket == null) { return; } // process messages for (int i = 0; i < outgoingPacket.MessageIds.Count; i++) { // remove acked message from send buffer ushort messageID = outgoingPacket.MessageIds[i]; if (sendBuffer.Exists(messageID)) { sendBuffer.Find(messageID).writeLock = true; sendBuffer.Remove(messageID); } } // update oldest unacked message bool allAcked = true; for (ushort sequence = oldestUnacked; sequence == this.sequence || PacketIO.SequenceLessThan(sequence, this.sequence); sequence++) { // if it's still in the send buffer, it hasn't been acked if (sendBuffer.Exists(sequence)) { oldestUnacked = sequence; allAcked = false; break; } } if (allAcked) { oldestUnacked = this.sequence; } }
protected void processSendBuffer() { int num = 0; ushort num2 = oldestUnacked; while (PacketIO.SequenceLessThan(num2, sequence)) { num++; num2 = (ushort)(num2 + 1); } ushort num3 = oldestUnacked; while (PacketIO.SequenceLessThan(num3, sequence) && num3 < oldestUnacked + 256) { BufferedPacket bufferedPacket = sendBuffer.Find(num3); if (bufferedPacket != null && !bufferedPacket.writeLock && !(time - bufferedPacket.time < 0.1)) { bool flag = false; if (!((bufferedPacket.buffer.Length >= config.FragmentThreshold) ? (messagePacker.Length + bufferedPacket.buffer.Length <= config.MaxPacketSize - 6 - 10) : (messagePacker.Length + bufferedPacket.buffer.Length <= config.FragmentThreshold - 10))) { flushMessagePacker(); } bufferedPacket.time = time; int length = messagePacker.Length; messagePacker.SetSize(messagePacker.Length + bufferedPacket.buffer.Length); messagePacker.BufferCopy(bufferedPacket.buffer, 0, length, bufferedPacket.buffer.Length); tempList.Add(num3); lastMessageSend = time; } num3 = (ushort)(num3 + 1); } if (time - lastMessageSend >= 0.1) { sendAckPacket(); lastMessageSend = time; } flushMessagePacker(); }
public override void SendMessage(byte[] buffer, int bufferLength) { int num = 0; ushort num2 = oldestUnacked; while (PacketIO.SequenceLessThan(num2, sequence)) { if (sendBuffer.Exists(num2)) { num++; } num2 = (ushort)(num2 + 1); } if (num == sendBuffer.Size) { ByteBuffer byteBuffer = ObjPool <ByteBuffer> .Get(); byteBuffer.SetSize(bufferLength); byteBuffer.BufferCopy(buffer, 0, 0, bufferLength); messageQueue.Enqueue(byteBuffer); } else { ushort val = sequence++; BufferedPacket bufferedPacket = sendBuffer.Insert(val); bufferedPacket.time = -1.0; int variableLengthBytes = getVariableLengthBytes((ushort)bufferLength); bufferedPacket.buffer.SetSize(bufferLength + 2 + variableLengthBytes); using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(bufferedPacket.buffer.InternalBuffer)) { byteArrayReaderWriter.Write(val); writeVariableLengthUShort((ushort)bufferLength, byteArrayReaderWriter); byteArrayReaderWriter.WriteBuffer(buffer, bufferLength); } bufferedPacket.writeLock = false; } }
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 bool TestInsert(ushort sequence) { return(!PacketIO.SequenceLessThan(sequence, (ushort)(this.sequence - numEntries))); }
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(); } }