예제 #1
0
        public override AnalyzedPacket Filter(ref ReadOnlySequence <byte> buffer)
        {
            try
            {
                if (buffer.Length < HEADER_SIZE)
                {
                    return(null);
                }

                var woringSpan = buffer.First.Span;

                var packetTotalSize = C3SockNetUtil.FastBinaryRead.UInt16(woringSpan, 0);
                var BodySize        = (UInt16)(packetTotalSize - HEADER_SIZE);
                var ProtocolId      = C3SockNetUtil.FastBinaryRead.UInt16(woringSpan, 2);
                var PacketType      = C3SockNetUtil.FastBinaryRead.SByte(woringSpan, 4);

                if (BodySize == 0)
                {
                    var packet = new AnalyzedPacket
                    {
                        SessionUniqueId = 0,
                        PacketId        = ProtocolId,
                        Head            = null,
                        Body            = buffer.ToArray()
                    };

                    buffer = buffer.Slice(packetTotalSize);
                    return(packet);
                }
                else if (BodySize > 0 && (packetTotalSize >= buffer.Length))
                {
                    var packet = new AnalyzedPacket
                    {
                        SessionUniqueId = 0,
                        PacketId        = ProtocolId,
                        Head            = null,
                        Body            = buffer.Slice(HEADER_SIZE, BodySize).ToArray()
                    };

                    buffer = buffer.Slice(packetTotalSize);
                    return(packet);
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception ex)
            {
                GLogging.Logger().LogError($"Failed to Filter {ex.ToString()}");
                return(null);
            }
        }
        public override AnalyzedPacket Filter(ref ReadOnlySequence <byte> buffer)
        {
            try
            {
                ReadOnlySequence <byte> slice;
                SequencePosition        cursor;

                if (!buffer.TrySliceTo(CheckFunc, out slice, out cursor))
                {
                    return(null);
                }

                buffer = buffer.Slice(cursor).Slice(TerminatorLen);
                return(ResolvePackage(slice));
            }
            catch (Exception ex)
            {
                GLogging.Logger().LogError($"Failed to Filter {ex.ToString()}");
                return(null);
            }
        }
        public override async Task ProcessRequest()
        {
            var input = _transportConnection.Transport.Input;//_transportConnection.Application.Input;
            var currentPipelineFilter = _pipelineFilter;

            try
            {
                while (true)
                {
                    var result = await input.ReadAsync();

                    var buffer = result.Buffer;

                    if (result.IsCompleted)
                    {
                        OnClosed();
                        break;
                    }

                    while (true)
                    {
                        var packageInfo = currentPipelineFilter.Filter(ref buffer);

                        if (currentPipelineFilter.NextFilter != null)
                        {
                            _pipelineFilter = currentPipelineFilter = currentPipelineFilter.NextFilter;
                        }

                        if (packageInfo == null)
                        {
                            break;
                        }

                        OnPackageReceived(packageInfo);

                        if (buffer.Length == 0)
                        {
                            break;
                        }
                    }

                    // AdvanceTo를 안하면 다음 ReadAsync에서 에러 발생으로 접속이 끊어진다.
                    input.AdvanceTo(buffer.Start, buffer.End);
                }
            }
            catch // 접속이 끊어지면 catch가 호출된다
            {
                OnClosed();
                GLogging.Logger().LogDebug($"Dis Connected: {_transportConnection.ConnectionId} , threadId:{System.Threading.Thread.CurrentThread.ManagedThreadId}");
            }
            finally
            {
                input.Complete();

                //가끔 여기서 예외발생. Kesterl의 SocketConnection 에서  ThreadPool.UnsafeQueueUserWorkItem 쯤에서 발생
                //크게 중요하지는 않는 듯 하다. Send를 하지 않는데 Complet 시켜서 그렇지 않을까라고 생각한다
                // 주석 처리하면 예외 발생하지 않고, 접속 끊어지는 것도 잘됨.
                //TODO echo 테스트 등에서도 문제 없는지 확인 필요
                //_transportConnection.Transport.Output.Complete();
            }

            await Task.CompletedTask;
        }