示例#1
0
        protected override void Handle(MercuryPacket packet)
        {
            using var stream = new MemoryStream(packet.Payload);
            int seqLength = getShort(packet.Payload, (int)stream.Position, true);

            stream.Seek(2, SeekOrigin.Current);
            long seq    = 0;
            var  buffer = packet.Payload;

            switch (seqLength)
            {
            case 2:
                seq = getShort(packet.Payload, (int)stream.Position, true);
                stream.Seek(2, SeekOrigin.Current);
                break;

            case 4:
                seq = getInt(packet.Payload, (int)stream.Position, true);
                stream.Seek(4, SeekOrigin.Current);
                break;

            case 8:
                seq = getLong(packet.Payload, (int)stream.Position, true);
                stream.Seek(8, SeekOrigin.Current);
                break;
            }


            byte flags = packet.Payload[(int)stream.Position];

            stream.Seek(1, SeekOrigin.Current);
            short parts = getShort(packet.Payload, (int)stream.Position, true);

            stream.Seek(2, SeekOrigin.Current);



            _partials.TryGetValue(seq, out var partial);
            if (partial == null || flags == 0)
            {
                partial = new BytesArrayList();
                _partials.TryAdd(seq, partial);
            }

            Debug.WriteLine($"Handling packet, cmd: {packet.Cmd}, seq: {seq}, flags: {flags}, parts: {parts}");

            for (int j = 0; j < parts; j++)
            {
                short size = getShort(packet.Payload, (int)stream.Position, true);
                stream.Seek(2, SeekOrigin.Current);

                byte[] buffer2 = new byte[size];

                int end = buffer2.Length;
                for (int z = 0; z < end; z++)
                {
                    byte a = packet.Payload[(int)stream.Position];
                    stream.Seek(1, SeekOrigin.Current);
                    buffer2[z] = a;
                }

                partial.Add(buffer2);
            }

            if (flags != 1)
            {
                return;
            }

            _partials.TryRemove(seq, out partial);

            Header header;

            try
            {
                header = Header.Parser.ParseFrom(partial.First());
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Couldn't parse header! bytes: {Utils.bytesToHex(partial.First())}");
                throw ex;
            }

            var resp = new MercuryResponse(header, partial);

            switch (packet.Cmd)
            {
            case MercuryPacket.Type.MercuryEvent:
                bool dispatched = false;
                lock (_subscriptions)
                {
                    foreach (var sub in _subscriptions)
                    {
                        if (sub.Matches(header.Uri))
                        {
                            sub.Dispatch(resp);
                            dispatched = true;
                        }
                    }
                }

                if (!dispatched)
                {
                    Debug.WriteLine(
                        $"Couldn't dispatch Mercury event seq: {seq}, uri: {header.Uri}, code: {header.StatusCode}, payload: {resp.Payload.ToHex()}");
                }

                break;

            case MercuryPacket.Type.MercuryReq:
            case MercuryPacket.Type.MercurySub:
            case MercuryPacket.Type.MercuryUnsub:
                _callbacks.TryRemove(seq, out var val);
                if (val != null)
                {
                    val.Response(resp);
                }
                else
                {
                    Debug.WriteLine(
                        $"Skipped Mercury response, seq: {seq}, uri: {header.Uri}, code: {header.StatusCode}");
                }

                lock (_removeCallbackLock)
                {
                    _removeCallbackLock.Reset();
                }
                break;

            default:
                Debugger.Break();
                break;
            }
        }
示例#2
0
 protected virtual void AppendToQueue([NotNull] MercuryPacket packet)
 {
     _worker.Invoke(packet);
 }
示例#3
0
 protected abstract void Handle([NotNull] MercuryPacket packet);
示例#4
0
 public void Dispatch(MercuryPacket packet) => AppendToQueue(packet);