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; } }
protected virtual void AppendToQueue([NotNull] MercuryPacket packet) { _worker.Invoke(packet); }
protected abstract void Handle([NotNull] MercuryPacket packet);
public void Dispatch(MercuryPacket packet) => AppendToQueue(packet);