private async Task HandleSession(AppSession session)
        {
            Interlocked.Increment(ref _sessionCount);

            try
            {
                _logger.LogInformation($"A new session connected: {session.SessionID}");
                session.OnSessionConnected();

                var channel = session.Channel as IChannel <TReceivePackageInfo>;

                await foreach (var p in channel.RunAsync())
                {
                    await _packageHandler?.Handle(session, p);
                }

                _logger.LogInformation($"The session disconnected: {session.SessionID}");

                session.OnSessionClosed(EventArgs.Empty);
            }
            catch (Exception e)
            {
                _logger.LogError($"Failed to handle the session {session.SessionID}.", e);
            }

            Interlocked.Decrement(ref _sessionCount);
        }
示例#2
0
        private async ValueTask HandleSession(AppSession session, IChannel channel)
        {
            var result = await InitializeSession(session, channel);

            if (!result)
            {
                return;
            }

            try
            {
                Interlocked.Increment(ref _sessionCount);

                _logger.LogInformation($"A new session connected: {session.SessionID}");
                session.OnSessionConnected();

                var packageChannel = channel as IChannel <TReceivePackageInfo>;

                await foreach (var p in packageChannel.RunAsync())
                {
                    try
                    {
                        await _packageHandler?.Handle(session, p);
                    }
                    catch (Exception e)
                    {
                        var toClose = await _errorHandler(session, new PackageHandlingException <TReceivePackageInfo>($"Session {session.SessionID} got an error when handle a package.", p, e));

                        if (toClose)
                        {
                            session.Close();
                        }
                    }
                }

                _logger.LogInformation($"The session disconnected: {session.SessionID}");

                session.OnSessionClosed(EventArgs.Empty);
            }
            catch (Exception e)
            {
                _logger.LogError($"Failed to handle the session {session.SessionID}.", e);
            }
            finally
            {
                Interlocked.Decrement(ref _sessionCount);
            }
        }
示例#3
0
        private async ValueTask HandleSession(AppSession session, IChannel channel)
        {
            if (!await InitializeSession(session, channel))
            {
                return;
            }

            try
            {
                await FireSessionConnectedEvent(session);

                var packageChannel = channel as IChannel <TReceivePackageInfo>;

                await foreach (var p in packageChannel.RunAsync())
                {
                    try
                    {
                        await _packageHandler?.Handle(session, p);
                    }
                    catch (Exception e)
                    {
                        var toClose = await _errorHandler(session, new PackageHandlingException <TReceivePackageInfo>($"Session {session.SessionID} got an error when handle a package.", p, e));

                        if (toClose)
                        {
                            session.Close();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"Failed to handle the session {session.SessionID}.");
            }
            finally
            {
                await FireSessionClosedEvent(session);
            }
        }
        /// <summary>
        /// Processes the input segment.
        /// </summary>
        /// <param name="segment">The input segment.</param>
        /// <param name="state">The buffer state.</param>
        /// <returns>
        /// the processing result
        /// </returns>
        public virtual ProcessResult Process(ArraySegment <byte> segment, IBufferState state)
        {
            m_ReceiveCache.Add(segment, state);

            var rest = 0;

            while (true)
            {
                var packageInfo = m_ReceiveFilter.Filter(m_ReceiveCache, out rest);

                if (m_ReceiveFilter.State == FilterState.Error)
                {
                    m_BufferRecycler.Return(m_ReceiveCache.GetAllCachedItems(), 0, m_ReceiveCache.Count);
                    return(ProcessResult.Create(ProcessState.Error));
                }

                if (m_MaxPackageLength > 0)
                {
                    var length = m_ReceiveCache.Total;

                    if (length > m_MaxPackageLength)
                    {
                        m_BufferRecycler.Return(m_ReceiveCache.GetAllCachedItems(), 0, m_ReceiveCache.Count);
                        return(ProcessResult.Create(ProcessState.Error, string.Format("Max package length: {0}, current processed length: {1}", m_MaxPackageLength, length)));
                    }
                }

                //Receive continue
                if (packageInfo == null)
                {
                    if (rest > 0)
                    {
                        PushResetData(segment, rest, state);
                        continue;
                    }

                    return(ProcessResult.Create(ProcessState.Cached));
                }

                m_ReceiveFilter.Reset();

                var nextReceiveFilter = m_ReceiveFilter.NextReceiveFilter;

                if (nextReceiveFilter != null)
                {
                    m_ReceiveFilter = nextReceiveFilter;
                }

                m_PackageHandler.Handle(packageInfo);

                if (packageInfo is IBufferedPackageInfo && // is a buffered package
                    (packageInfo as IBufferedPackageInfo).Data is BufferList)        // and it uses receive buffer directly
                {
                    // so we need to create a new receive buffer container to use
                    m_ReceiveCache = new BufferList();

                    if (rest <= 0)
                    {
                        return(ProcessResult.Create(ProcessState.Cached));
                    }
                }
                else
                {
                    ReturnOtherThanLastBuffer();

                    if (rest <= 0)
                    {
                        return(ProcessResult.Create(ProcessState.Completed));
                    }
                }

                PushResetData(segment, rest, state);
            }
        }
 public override async ValueTask Handle(IAppSession session, WebSocketPackage package)
 {
     await _commandMiddleware.Handle(session, package);
 }
        public virtual ProcessResult Process(ArraySegment <byte> segment, IBufferState state)
        {
            m_ReceiveCache.Add(segment, state);

            var rest = 0;

            while (true)
            {
                var packageInfo = m_ReceiveFilter.Filter(m_ReceiveCache, out rest);

                if (m_ReceiveFilter.State == FilterState.Error)
                {
                    m_BufferRecycler.Return(m_ReceiveCache.GetAllCachedItems(), 0, m_ReceiveCache.Count);
                    return(ProcessResult.Create(ProcessState.Error));
                }

                if (m_MaxPackageLength > 0)
                {
                    var length = m_ReceiveCache.Total;

                    if (length > m_MaxPackageLength)
                    {
                        m_BufferRecycler.Return(m_ReceiveCache.GetAllCachedItems(), 0, m_ReceiveCache.Count);
                        return(ProcessResult.Create(ProcessState.Error, string.Format("Max package length: {0}, current processed length: {1}", m_MaxPackageLength, length)));
                    }
                }

                //Receive continue
                if (packageInfo == null)
                {
                    if (rest > 0)
                    {
                        PushResetData(segment, rest, state);
                        continue;
                    }

                    //Because the current buffer is cached, so new buffer is required for receiving
                    FireNewReceiveBufferRequired();
                    return(ProcessResult.Create(ProcessState.Cached));
                }

                m_ReceiveFilter.Reset();

                var nextReceiveFilter = m_ReceiveFilter.NextReceiveFilter;

                if (nextReceiveFilter != null)
                {
                    m_ReceiveFilter = nextReceiveFilter;
                }

                m_PackageHandler.Handle(packageInfo);

                if (packageInfo is IRawPackageInfo)
                {
                    m_ReceiveCache = new ReceiveCache();

                    if (rest <= 0)
                    {
                        return(ProcessResult.Create(ProcessState.Cached));
                    }
                }
                else
                {
                    ReturnOtherThanLastBuffer();

                    if (rest <= 0)
                    {
                        return(ProcessResult.Create(ProcessState.Completed));
                    }
                }

                PushResetData(segment, rest, state);
            }
        }