/// <summary> /// Returns this object back to the object pool from whence it came. /// </summary> public void Recycle() { this.Acknowledged = true; this.Connection = null; PacketPool.PutObject(this); }
// Packets resent public async ValueTask <int> Resend() { UdpConnection connection = this.Connection; if (!this.Acknowledged && connection != null) { long lifetime = this.Stopwatch.ElapsedMilliseconds; if (lifetime >= connection.DisconnectTimeout) { if (connection.reliableDataPacketsSent.TryRemove(this.Id, out Packet self)) { await connection.DisconnectInternal(HazelInternalErrors.ReliablePacketWithoutResponse, $"Reliable packet {self.Id} (size={this.Length}) was not ack'd after {lifetime}ms ({self.Retransmissions} resends)"); self.Recycle(); } return(0); } if (lifetime >= this.NextTimeout) { ++this.Retransmissions; if (connection.ResendLimit != 0 && this.Retransmissions > connection.ResendLimit) { if (connection.reliableDataPacketsSent.TryRemove(this.Id, out Packet self)) { await connection.DisconnectInternal(HazelInternalErrors.ReliablePacketWithoutResponse, $"Reliable packet {self.Id} (size={this.Length}) was not ack'd after {self.Retransmissions} resends ({lifetime}ms)"); self.Recycle(); } return(0); } this.NextTimeout += (int)Math.Min(this.NextTimeout * connection.ResendPingMultiplier, 1000); try { await connection.WriteBytesToConnection(this.Data, this.Length); connection.Statistics.LogMessageResent(); return(1); } catch (InvalidOperationException) { await connection.DisconnectInternal(HazelInternalErrors.ConnectionDisconnected, "Could not resend data as connection is no longer connected"); } } } return(0); }
internal void Set(ushort id, UdpConnection connection, byte[] data, int length, int timeout, Action ackCallback) { this.Id = id; this.Data = data; this.Connection = connection; this.Length = length; this.Acknowledged = false; this.NextTimeout = timeout; this.AckCallback = ackCallback; this.Retransmissions = 0; this.Stopwatch.Restart(); }