示例#1
0
        public override void ServerLateUpdate()
        {
            // flush reliable messages after latency
            while (reliableServerToClient.Count > 0)
            {
                // check the first message time
                QueuedMessage message = reliableServerToClient[0];
                if (message.time + reliableLatency <= Time.time)
                {
                    // send and eat
                    wrap.ServerSend(message.connectionId, Channels.Reliable, new ArraySegment <byte>(message.bytes));
                    reliableServerToClient.RemoveAt(0);
                }
                // not enough time elapsed yet
                break;
            }

            // flush unreliable messages after latency
            while (unreliableServerToClient.Count > 0)
            {
                // check the first message time
                QueuedMessage message = unreliableServerToClient[0];
                if (message.time + unreliableLatency <= Time.time)
                {
                    // send and eat
                    wrap.ServerSend(message.connectionId, Channels.Unreliable, new ArraySegment <byte>(message.bytes));
                    unreliableServerToClient.RemoveAt(0);
                }
                // not enough time elapsed yet
                break;
            }

            // update wrapped transport too
            wrap.ServerLateUpdate();
        }
示例#2
0
        public override void ServerLateUpdate()
        {
            // flush reliable messages that are ready to be sent
            // => list isn't ordered (due to scramble). need to iterate all.
            for (int i = 0; i < reliableServerToClient.Count; ++i)
            {
                QueuedMessage message = reliableServerToClient[i];
                if (Time.time >= message.timeToSend)
                {
                    // send and remove
                    wrap.ServerSend(message.connectionId, Channels.DefaultReliable, new ArraySegment <byte>(message.bytes));
                    reliableServerToClient.RemoveAt(i);
                    --i;
                }
            }

            // flush unrelabe messages that are ready to be sent
            // => list isn't ordered (due to scramble). need to iterate all.
            for (int i = 0; i < unreliableServerToClient.Count; ++i)
            {
                QueuedMessage message = unreliableServerToClient[i];
                if (Time.time >= message.timeToSend)
                {
                    // send and remove
                    wrap.ServerSend(message.connectionId, Channels.DefaultUnreliable, new ArraySegment <byte>(message.bytes));
                    unreliableServerToClient.RemoveAt(i);
                    --i;
                }
            }

            // update wrapped transport too
            wrap.ServerLateUpdate();
        }
示例#3
0
        public override void ClientLateUpdate()
        {
            // flush reliable messages after latency
            while (reliableClientToServer.Count > 0)
            {
                // check the first message time
                QueuedMessage message = reliableClientToServer[0];
                if (message.time <= Time.time)
                {
                    // send and eat
                    wrap.ClientSend(new ArraySegment <byte>(message.bytes), Channels.Reliable);
                    reliableClientToServer.RemoveAt(0);
                }
                // not enough time elapsed yet
                break;
            }

            // flush unreliable messages after latency
            while (unreliableClientToServer.Count > 0)
            {
                // check the first message time
                QueuedMessage message = unreliableClientToServer[0];
                if (message.time <= Time.time)
                {
                    // send and eat
                    wrap.ClientSend(new ArraySegment <byte>(message.bytes), Channels.Unreliable);
                    unreliableClientToServer.RemoveAt(0);
                }
                // not enough time elapsed yet
                break;
            }

            // update wrapped transport too
            wrap.ClientLateUpdate();
        }
示例#4
0
        // helper function to simulate a send with latency/loss/scramble
        void SimulateSend(int connectionId, int channelId, ArraySegment <byte> segment, List <QueuedMessage> reliableQueue, List <QueuedMessage> unreliableQueue)
        {
            // segment is only valid after returning. copy it.
            // (allocates for now. it's only for testing anyway.)
            byte[] bytes = new byte[segment.Count];
            Buffer.BlockCopy(segment.Array, segment.Offset, bytes, 0, segment.Count);

            // enqueue message. send after latency interval.
            QueuedMessage message = new QueuedMessage
            {
                connectionId = connectionId,
                bytes        = bytes
            };

            switch (channelId)
            {
            case Channels.DefaultReliable:
                // simulate latency & spikes
                message.timeToSend = Time.time + SimulateLatency(reliableLatency, reliableLatencySpikes);
                reliableQueue.Add(message);
                break;

            case Channels.DefaultUnreliable:
                // simulate packet loss
                bool drop = random.NextDouble() < unreliableLoss;
                if (!drop)
                {
                    // simulate scramble (Random.Next is < max, so +1)
                    // note that list entries are NOT ordered by time anymore
                    // after inserting randomly.
                    int last  = unreliableQueue.Count;
                    int index = unreliableScramble ? random.Next(0, last + 1) : last;

                    // simulate latency & spikes
                    message.timeToSend = Time.time + SimulateLatency(unreliableLatency, unreliableLatencySpikes);
                    unreliableQueue.Insert(index, message);
                }
                break;

            default:
                Debug.LogError($"{nameof(LatencySimulation)} unexpected channelId: {channelId}");
                break;
            }
        }
示例#5
0
        // helper function to simulate a send with latency/loss/scramble
        void SimulateSend(int connectionId, int channelId, ArraySegment <byte> segment, float latency, List <QueuedMessage> reliableQueue, List <QueuedMessage> unreliableQueue)
        {
            // segment is only valid after returning. copy it.
            // (allocates for now. it's only for testing anyway.)
            byte[] bytes = new byte[segment.Count];
            Buffer.BlockCopy(segment.Array, segment.Offset, bytes, 0, segment.Count);

            // enqueue message. send after latency interval.
            QueuedMessage message = new QueuedMessage
            {
                connectionId = connectionId,
                bytes        = bytes,
                time         = Time.time + latency
            };

            switch (channelId)
            {
            case Channels.Reliable:
                // simulate latency
                reliableQueue.Add(message);
                break;

            case Channels.Unreliable:
                // simulate packet loss
                bool drop = random.NextDouble() < unreliableLoss;
                if (!drop)
                {
                    // simulate scramble (Random.Next is < max, so +1)
                    bool scramble = random.NextDouble() < unreliableScramble;
                    int  last     = unreliableQueue.Count;
                    int  index    = scramble ? random.Next(0, last + 1) : last;

                    // simulate latency
                    unreliableQueue.Insert(index, message);
                }
                break;

            default:
                Debug.LogError($"{nameof(LatencySimulation)} unexpected channelId: {channelId}");
                break;
            }
        }