* OutgoingPacket fixes, needs more testing with slow/disconnected clients
* Switch AvatarPropertiesRequestHandler to use actual profile data
* Switch AvatarWearablesRequestHandler to use actual wearables data
* Respond to AgentCachedTexture inquiries with empty cache data
* Improve UUIDNameRequest performance

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2252 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
John Hurliman
2008-10-01 00:17:49 +00:00
parent eaaef001fb
commit 02ebca8b02
2 changed files with 258 additions and 141 deletions

View File

@@ -14,36 +14,17 @@ namespace Simian
public Packet Packet;
}
public struct OutgoingPacket
public class OutgoingPacket
{
public UDPClient Client;
public Packet Packet;
/// <summary>Number of times this packet has been resent</summary>
public int ResendCount;
/// <summary>Environment.TickCount when this packet was last sent over the wire</summary>
public int TickCount;
public OutgoingPacket(UDPClient client, Packet packet)
public OutgoingPacket(Packet packet)
{
Client = client;
Packet = packet;
ResendCount = 0;
TickCount = 0;
}
public void IncrementResendCount()
{
++ResendCount;
}
public void SetTickCount()
{
TickCount = Environment.TickCount;
}
public void ZeroTickCount()
{
TickCount = 0;
}
}
@@ -250,16 +231,9 @@ namespace Simian
if (packet.Header.Reliable)
{
// Wrap this packet in a struct to track timeouts and resends
OutgoingPacket outgoing = new OutgoingPacket(null, packet);
// Keep track of when this packet was sent out (right now)
outgoing.TickCount = Environment.TickCount;
OutgoingPacket outgoing;
// Add this packet to the list of ACK responses we are waiting on from this client
lock (client.NeedAcks)
client.NeedAcks[sequence] = outgoing;
if (packet.Header.Resent)
if (packet.Header.Resent && client.NeedAcks.TryGetValue(packet.Header.Sequence, out outgoing))
{
// This packet has already been sent out once, strip any appended ACKs
// off it and reinsert them into the outgoing ACK queue under the
@@ -282,12 +256,16 @@ namespace Simian
packet.Header.AppendedAcks = false;
packet.Header.AckList = new uint[0];
}
// Update the sent time for this packet
SetResentTime(client, packet.Header.Sequence);
}
else
{
// Wrap this packet in a struct to track timeouts and resends
outgoing = new OutgoingPacket(packet);
// Add this packet to the list of ACK responses we are waiting on from this client
lock (client.NeedAcks)
client.NeedAcks[sequence] = outgoing;
// This packet is not a resend, check if the conditions are favorable
// to ACK appending
if (packet.Type != PacketType.PacketAck)
@@ -310,6 +288,9 @@ namespace Simian
}
}
}
// Update the sent time for this packet
outgoing.TickCount = Environment.TickCount;
}
else if (packet.Header.AckList.Length > 0)
{
@@ -401,13 +382,6 @@ namespace Simian
SendPacket(client, acks, PacketCategory.Overhead, true);
}
void SetResentTime(UDPClient client, uint sequence)
{
OutgoingPacket outgoing;
if (client.NeedAcks.TryGetValue(sequence, out outgoing))
outgoing.SetTickCount();
}
public void ResendUnacked(UDPClient client)
{
lock (client.NeedAcks)
@@ -425,34 +399,29 @@ namespace Simian
Logger.DebugLog(String.Format("Resending packet #{0} ({1}), {2}ms have passed",
outgoing.Packet.Header.Sequence, outgoing.Packet.GetType(), now - outgoing.TickCount));
outgoing.ZeroTickCount();
outgoing.TickCount = 0;
outgoing.Packet.Header.Resent = true;
++outgoing.ResendCount;
//++Stats.ResentPackets;
outgoing.IncrementResendCount();
SendPacket(client, outgoing.Packet, PacketCategory.Overhead, false);
}
else
{
Logger.Log(String.Format("Dropping packet #{0} ({1}) after {2} failed attempts",
outgoing.Packet.Header.Sequence, outgoing.Packet.GetType(), outgoing.ResendCount), Helpers.LogLevel.Warning);
outgoing.Packet.Header.Sequence, outgoing.Packet.GetType(), outgoing.ResendCount),
Helpers.LogLevel.Warning);
dropAck.Add(outgoing.Packet.Header.Sequence);
//Disconnect an agent if no packets are received for some time
//TODO: Send logout packet? Also, 60000 should be a setting somewhere.
//TODO: 60000 should be a setting somewhere.
if (Environment.TickCount - client.Agent.TickLastPacketReceived > 60000)
{
Logger.Log(String.Format("Ack timeout for {0}, disconnecting", client.Agent.Avatar.Name), Helpers.LogLevel.Warning);
server.UDP.RemoveClient(client.Agent);
//HACK: Notify everyone when someone is disconnected
OfflineNotificationPacket offline = new OfflineNotificationPacket();
offline.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[1];
offline.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock();
offline.AgentBlock[0].AgentID = client.Agent.AgentID;
server.UDP.BroadcastPacket(offline, PacketCategory.State);
Logger.Log(String.Format("Ack timeout for {0}, disconnecting", client.Agent.Avatar.Name),
Helpers.LogLevel.Warning);
server.DisconnectClient(client.Agent);
return;
}
}