protected void processPacket(ushort seq, byte[] packetData, int packetLen)
 {
     using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(packetData))
     {
         while (byteArrayReaderWriter.ReadPosition < packetLen)
         {
             ushort num  = byteArrayReaderWriter.ReadUInt16();
             ushort num2 = readVariableLengthUShort(byteArrayReaderWriter);
             if (num2 != 0)
             {
                 if (!receiveBuffer.Exists(num))
                 {
                     BufferedPacket bufferedPacket = receiveBuffer.Insert(num);
                     bufferedPacket.buffer.SetSize(num2);
                     byteArrayReaderWriter.ReadBytesIntoBuffer(bufferedPacket.buffer.InternalBuffer, num2);
                 }
                 else
                 {
                     byteArrayReaderWriter.SeekRead(byteArrayReaderWriter.ReadPosition + (int)num2);
                 }
                 while (receiveBuffer.Exists(nextReceive))
                 {
                     BufferedPacket bufferedPacket2 = receiveBuffer.Find(nextReceive);
                     ReceiveCallback(ChannelID, bufferedPacket2.buffer.InternalBuffer, bufferedPacket2.buffer.Length);
                     receiveBuffer.Remove(nextReceive);
                     nextReceive++;
                 }
             }
         }
     }
 }
        // process incoming packets and turn them into messages
        protected void processPacket(ushort seq, byte[] packetData, int packetLen)
        {
            using (var reader = ByteArrayReaderWriter.Get(packetData))
            {
                while (reader.ReadPosition < packetLen)
                {
                    // get message bytes and send to receive callback
                    ushort messageID     = reader.ReadUInt16();
                    ushort messageLength = readVariableLengthUShort(reader);

                    if (messageLength == 0)
                    {
                        continue;
                    }

                    if (!receiveBuffer.Exists(messageID))
                    {
                        var receivedMessage = receiveBuffer.Insert(messageID);

                        receivedMessage.buffer.SetSize(messageLength);
                        reader.ReadBytesIntoBuffer(receivedMessage.buffer.InternalBuffer, messageLength);
                    }
                    else
                    {
                        reader.SeekRead(reader.ReadPosition + messageLength);
                    }

                    // keep returning the next message we're expecting as long as it's available
                    while (receiveBuffer.Exists(nextReceive))
                    {
                        var msg = receiveBuffer.Find(nextReceive);

                        ReceiveCallback(msg.buffer.InternalBuffer, msg.buffer.Length);

                        receiveBuffer.Remove(nextReceive);
                        nextReceive++;
                    }
                }
            }
        }
Example #3
0
 public UnreliableMessageChannel()
 {
     receiveBuffer = new SequenceBuffer <ReceivedPacketData>(256);
     config        = ReliableConfig.DefaultConfig();
     config.TransmitPacketCallback = delegate(byte[] buffer, int size)
     {
         TransmitCallback(buffer, size);
     };
     config.ProcessPacketCallback = delegate(ushort seq, byte[] buffer, int size)
     {
         if (!receiveBuffer.Exists(seq))
         {
             receiveBuffer.Insert(seq);
             ReceiveCallback(ChannelID, buffer, size);
         }
     };
     packetController = new ReliablePacketController(config, DateTime.Now.GetTotalSeconds());
 }
        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 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();
            }
        }