Ejemplo n.º 1
0
 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)));
 }
Ejemplo n.º 2
0
        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);
                }
            }));
        }