ToFixedLenFrameSubject(this Socket socket, ISimpleFrameEncoder encoder, IFixedLenFrameDecoder decoder, SyncBufManager bufferManager, CancellationToken token) { return(Subject.Create <DisposableValue <ArraySegment <byte> >, DisposableValue <ArraySegment <byte> > >( socket.ToFrameClientObserver(encoder, token, bufferManager), socket.ToFixedLenFrameObservable(bufferManager, decoder))); }
public static IObservable <DisposableValue <ArraySegment <byte> > > ToFixedLenFrameObservable(this Socket socket, SyncBufManager bufferManager, IFixedLenFrameDecoder decoder) { return(Observable.Create <DisposableValue <ArraySegment <byte> > >(async(observer, token) => { var receivedFlag = decoder.ReceivedFlags; var decoderLenByteCount = decoder.LenByteCount; var hc = 1 + decoderLenByteCount; var decoderHeader = decoder.Header; var decoderTail = decoder.Tail; var headerBuffer = new byte[hc]; try { while (!token.IsCancellationRequested) { if (await socket.ReceiveCompletelyAsync(headerBuffer, hc, receivedFlag, token) != hc) { break; } if (headerBuffer[0] != decoderHeader) { AppLogger.Warning($"corruted packet: invalid frame header"); break; } var length = LengthBitConverter.FromByte(headerBuffer, 1, decoderLenByteCount) - 1; var buffer = bufferManager.TakeBuffer(length); if (await socket.ReceiveCompletelyAsync(buffer, length, receivedFlag, token) != length) { break; } var arraySegment = new ArraySegment <byte>(buffer, 0, length); observer.OnNext( new DisposableValue <ArraySegment <byte> >(arraySegment, Disposable.Create(() => bufferManager.ReturnBuffer(buffer)))); if (await socket.ReceiveAsync(headerBuffer, 0, 1, receivedFlag) == 0) { break; } if (headerBuffer[0] != decoderTail) { AppLogger.Warning($"corruted packet: invalid frame tail," + headerBuffer[0].Show()); break; } } observer.OnCompleted(); } catch (Exception error) { observer.OnError(error); } })); }