private void SendAck(ushort sequence) { // Check the last ack time if (!_lastAckTimes.TryGet(sequence, out NetTime value) || ((NetTime.Now - value).TotalMilliseconds > connection.SmoothRoundtrip * config.ReliabilityResendRoundtripMultiplier && (NetTime.Now - value).TotalMilliseconds > config.ReliabilityMinAckResendDelay)) { // Set the last ack time _lastAckTimes.Set(sequence, NetTime.Now); // Alloc ack memory HeapMemory ackMemory = memoryManager.AllocHeapMemory(4); // Write header ackMemory.Buffer[0] = HeaderPacker.Pack(MessageType.Ack); ackMemory.Buffer[1] = (byte)channelId; // Write sequence ackMemory.Buffer[2] = (byte)sequence; ackMemory.Buffer[3] = (byte)(sequence >> 8); // Send ack connection.SendInternal(new ArraySegment <byte>(ackMemory.Buffer, 0, 4), false); // Return memory memoryManager.DeAlloc(ackMemory); } }
private void SendAck(ushort sequence) { // Check the last ack time if (!_lastAckTimes.TryGet(sequence, out NetTime value) || ((NetTime.Now - value).TotalMilliseconds > connection.SmoothRoundtrip * config.ReliabilityResendRoundtripMultiplier && (NetTime.Now - value).TotalMilliseconds > config.ReliabilityMinAckResendDelay)) { // Set the last ack time _lastAckTimes.Set(sequence, NetTime.Now); // Alloc ack memory HeapMemory ackMemory = memoryManager.AllocHeapMemory(4 + (uint)(config.EnableMergedAcks ? config.MergedAckBytes : 0)); // Write header ackMemory.Buffer[0] = HeaderPacker.Pack(MessageType.Ack); ackMemory.Buffer[1] = (byte)channelId; // Write sequence ackMemory.Buffer[2] = (byte)sequence; ackMemory.Buffer[3] = (byte)(sequence >> 8); if (config.EnableMergedAcks) { // Reset the memory for (int i = 0; i < config.MergedAckBytes; i++) { ackMemory.Buffer[4 + i] = 0; } // Set the bit fields for (int i = 0; i < config.MergedAckBytes * 8; i++) { ushort bitSequence = (ushort)(sequence - (i + 1)); bool bitAcked = SequencingUtils.Distance(bitSequence, _incomingLowestAckedSequence, sizeof(ushort)) <= 0 || _incomingAckedSequences.Contains(bitSequence); if (bitAcked) { // Set the ack time for this packet _lastAckTimes.Set(bitSequence, NetTime.Now); } // Write single ack bit ackMemory.Buffer[4 + (i / 8)] |= (byte)((bitAcked ? 1 : 0) << (7 - (i % 8))); } } // Send ack connection.SendInternal(new ArraySegment <byte>(ackMemory.Buffer, 0, 4 + (config.EnableMergedAcks ? config.MergedAckBytes : 0)), false); // Return memory memoryManager.DeAlloc(ackMemory); } }