public void TestReadFlowManagement()
        {
            ReadCounter       counter = new ReadCounter();
            IByteBufferHolder first   = Message("first");
            IByteBufferHolder chunk   = Message("chunk");
            IByteBufferHolder last    = Message("last");

            var             agg      = new MockMessageAggregator(first, chunk, last);
            EmbeddedChannel embedded = new EmbeddedChannel(counter, agg);

            embedded.Configuration.IsAutoRead = false;

            Assert.False(embedded.WriteInbound(first));
            Assert.False(embedded.WriteInbound(chunk));
            Assert.True(embedded.WriteInbound(last));

            Assert.Equal(3, counter.Value); // 2 reads issued from MockMessageAggregator
                                            // 1 read issued from EmbeddedChannel constructor

            IByteBufferHolder all = new DefaultByteBufferHolder(Unpooled.WrappedBuffer(
                                                                    (IByteBuffer)first.Content.Retain(), (IByteBuffer)chunk.Content.Retain(), (IByteBuffer)last.Content.Retain()));
            var output = embedded.ReadInbound <IByteBufferHolder>();

            Assert.Equal(all, output);
            Assert.True(all.Release() && output.Release());
            Assert.False(embedded.Finish());
        }
 /// <summary>
 /// 执行下一步
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="byteBufferHolder"></param>
 /// <returns></returns>
 public async Task NextAsync(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder)
 {
     if (CanNext)
     {
         await _handlerContext.HandlerAsync(ctx, byteBufferHolder);
     }
 }
        public IFullHttpResponse HandlerException(IByteBufferHolder byteBufferHolder, Exception exception)
        {
            ConsoleHelper.ServerWriteError(exception);
            ResultModel resultModel = ResultModel.Fail("服务器错误,请联系后端工程师");

            return(HttpResponseHelper.GetHttpResponse(HttpResponseStatus.OK, resultModel.ToJson()));
        }
Beispiel #4
0
        string FormatByteBufferHolder(IChannelHandlerContext ctx, string eventName, IByteBufferHolder msg)
        {
            string      chStr   = ctx.Channel.ToString();
            string      msgStr  = msg.ToString();
            IByteBuffer content = msg.Content;
            int         length  = content.ReadableBytes;

            if (length == 0)
            {
                var buf = new StringBuilder(chStr.Length + 1 + eventName.Length + 2 + msgStr.Length + 4);
                buf.Append(chStr).Append(' ').Append(eventName).Append(", ").Append(msgStr).Append(", 0B");
                return(buf.ToString());
            }
            else
            {
                int rows = length / 16 + (length % 15 == 0 ? 0 : 1) + 4;
                var buf  = new StringBuilder(
                    chStr.Length + 1 + eventName.Length + 2 + msgStr.Length + 2 + 10 + 1 + 2 + rows * 80);

                buf.Append(chStr).Append(' ').Append(eventName).Append(": ")
                .Append(msgStr).Append(", ").Append(length).Append('B').Append('\n');
                ByteBufferUtil.AppendPrettyHexDump(buf, content);

                return(buf.ToString());
            }
        }
 /// <summary>
 /// 处理
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="ctx"></param>
 /// <param name="byteBufferHolder"></param>
 /// <param name="action"></param>
 /// <returns></returns>
 protected async Task HandlerAsync <T>(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder, Func <IChannelHandlerContext, T, Task> action)
 {
     if (byteBufferHolder is T target && action != null)
     {
         await action(ctx, target);
     }
     await NextAsync(ctx, byteBufferHolder);
 }
        RedisBulkStringAggregator(int maximumContentLength)
        {
            Contract.Requires(maximumContentLength > 0);

            this.maximumContentLength = maximumContentLength;
            this.maximumCumulationBufferComponents = DefaultMaximumCumulationBufferComponents;
            this.currentMessage = null;
        }
Beispiel #7
0
 public int Size(object msg)
 {
     return(msg switch
     {
         IByteBuffer byteBuffer => byteBuffer.ReadableBytes,
         IByteBufferHolder byteBufferHolder => byteBufferHolder.Content.ReadableBytes,
         IFileRegion fileRegion => 0,
         _ => _unknownSize,
     });
Beispiel #8
0
        void HandleWebSocketFrame(IChannelHandlerContext ctx, IByteBufferHolder frame)
        {
            switch (frame)
            {
            case CloseWebSocketFrame _:
                _handShaker.CloseAsync(ctx.Channel, (CloseWebSocketFrame)frame.Retain());
                ConsoleHelper.ConDepServerWriteLine($"连接{ctx.Channel.Id}已断开");
                return;

            case PingWebSocketFrame _:
                ctx.WriteAsync(new PongWebSocketFrame((IByteBuffer)frame.Content.Retain()));
                return;

            case PongWebSocketFrame _:
                ctx.WriteAsync(new PingWebSocketFrame((IByteBuffer)frame.Content.Retain()));
                return;

            case TextWebSocketFrame _:
                try
                {
                    string commandString = frame.Content.ReadString(frame.Content.WriterIndex, Encoding.UTF8);
                    var    command       = commandString.JsonToObject <Command>();
                    if (_webSocketConfig.NotShowCommandBlackList == null || _webSocketConfig.NotShowCommandBlackList.Length == 0 || !_webSocketConfig.NotShowCommandBlackList.Contains(command.HandlerName))
                    {
                        ConsoleHelper.ConDepServerWriteLine(command.HandlerName);
                    }

                    if (CanLoginSuccess(command))
                    {
                        Task.Run(async() => await SendCommand(ctx, commandString, command));
                    }
                    else
                    {
                        Task.Run(async() =>
                        {
                            var @event = new ServerErrorEvent
                            {
                                Status  = 401,
                                Message = "未登录"
                            };
                            await ctx.Channel.SendJsonEventAsync(@event);
                        });
                    }
                }
                catch (Exception ex)
                {
                    ConsoleHelper.ConDepServerErrorWriteLine(ex);
                    _logger.LogCritical(ex, ex.Message);
                }
                return;

            case BinaryWebSocketFrame binaryFrame:
                ctx.WriteAndFlushAsync(binaryFrame.Retain());
                break;
            }
        }
Beispiel #9
0
 public override async Task HandlerAsync(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder)
 {
     try
     {
         await HandlerAsync <IFullHttpRequest>(ctx, byteBufferHolder, HandlerRequestAsync);
     }
     catch (Exception exception)
     {
         OnException?.Invoke(exception);
         await HandlerExceptionAsync(ctx, byteBufferHolder, exception);
     }
 }
Beispiel #10
0
 public override async Task HandlerAsync(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder)
 {
     try
     {
         await base.HandlerAsync <IFullHttpRequest>(ctx, byteBufferHolder, HandlerRequestAsync);
     }
     catch (Exception e)
     {
         ShowException?.Invoke(e);
         var headers = GetDefaultHeaders("text/plain;charset=utf-8");
         IFullHttpResponse response = GetHttpResponse(HttpResponseStatus.InternalServerError, e.Message, headers);
         await SendHttpResponseAsync(ctx, response);
     }
 }
Beispiel #11
0
 public override async Task HandlerAsync(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder)
 {
     try
     {
         await HandlerAsync <IFullHttpRequest>(ctx, byteBufferHolder, HandlerRequestAsync);
     }
     catch (Exception exception)
     {
         OnException?.Invoke(exception);
         Dictionary <AsciiString, object> headers = HttpResponseHelper.GetDefaultHeaders("text/plain;charset=utf-8");
         IFullHttpResponse response = HttpResponseHelper.GetHttpResponse(HttpResponseStatus.InternalServerError, exception.Message, headers);
         await SendHttpResponseAsync(ctx, byteBufferHolder, response);
     }
 }
Beispiel #12
0
        public void EqualsAndHashCode()
        {
            var holder             = new DefaultByteBufferHolder(Unpooled.Empty);
            IByteBufferHolder copy = holder.Copy();

            try
            {
                Assert.Equal(holder, copy);
                Assert.Equal(holder.GetHashCode(), copy.GetHashCode());
            }
            finally
            {
                holder.Release();
                copy.Release();
            }
        }
        void InvokeHandleOversizedMessage(IChannelHandlerContext context, BulkStringHeaderRedisMessage startMessage)
        {
            Contract.Requires(context != null);
            Contract.Requires(startMessage != null);

            this.currentMessage = null;

            try
            {
                context.FireExceptionCaught(
                    new TooLongFrameException($"Content length exceeded {this.maximumContentLength} bytes."));
            }
            finally
            {
                // Release the message in case it is a full one.
                ReferenceCountUtil.Release(startMessage);
            }
        }
Beispiel #14
0
        void HandleWebSocketFrame(IChannelHandlerContext ctx, IByteBufferHolder frame)
        {
            switch (frame)
            {
            case CloseWebSocketFrame _:
                Task.Run(async() => {
                    await _handShaker.CloseAsync(ctx.Channel, (CloseWebSocketFrame)frame.Retain());
                });
                return;

            case PingWebSocketFrame _:
                ctx.WriteAsync(new PongWebSocketFrame((IByteBuffer)frame.Content.Retain()));
                return;

            case PongWebSocketFrame _:
                return;

            case TextWebSocketFrame _:
                try
                {
                    string commandString = frame.Content.ReadString(frame.Content.WriterIndex, Encoding.UTF8);
                    var    command       = commandString.JsonToObject <Command>();
                    var    commandBus    = TestServerHelper.ServiceProvider.GetRequiredService <ICommandBus>();
                    Task.Run(async() => {
                        await commandBus.SendAsync(ctx, commandString, command);
                    });
                }
                catch (Exception ex)
                {
                    ConsoleHelper.TestWriteLine(ex.Message, "未能解析事件");
                }
                return;

            case BinaryWebSocketFrame _:
                ctx.WriteAsync(frame.Retain());
                break;
            }
        }
        protected override void Decode(IChannelHandlerContext context, IRedisMessage message, List <object> output)
        {
            Contract.Requires(context != null);
            Contract.Requires(message != null);
            Contract.Requires(output != null);

            if (IsStartMessage(message)) // Start header
            {
                if (this.currentMessage != null)
                {
                    this.currentMessage.Release();
                    this.currentMessage = null;

                    throw new MessageAggregationException(
                              $"Start message {message} should have current buffer to be null.");
                }

                var startMessage = (BulkStringHeaderRedisMessage)message;
                if (IsContentLengthInvalid(startMessage, this.maximumContentLength))
                {
                    this.InvokeHandleOversizedMessage(context, startMessage);
                }

                // A streamed message -initialize the cumulative buffer, and wait for incoming chunks.
                CompositeByteBuffer buffer = context.Allocator.CompositeBuffer(this.maximumCumulationBufferComponents);
                this.currentMessage = BeginAggregation(buffer);
            }
            else if (IsContentMessage(message)) // Content
            {
                if (this.currentMessage == null)
                {
                    // it is possible that a TooLongFrameException was already thrown but we can still discard data
                    // until the begging of the next request/response.
                    return;
                }
                // Merge the received chunk into the content of the current message.
                var content = (CompositeByteBuffer)this.currentMessage.Content;

                var bufferHolder = (IByteBufferHolder)message;

                // Handle oversized message.
                if (content.ReadableBytes > this.maximumContentLength - bufferHolder.Content.ReadableBytes)
                {
                    // By convention, full message type extends first message type.

                    // ReSharper disable once PossibleInvalidCastException
                    var startMessage = (BulkStringHeaderRedisMessage)message;
                    this.InvokeHandleOversizedMessage(context, startMessage);

                    return;
                }

                // Append the content of the chunk.
                AppendPartialContent(content, bufferHolder.Content);

                bool isLast = IsLastContentMessage(message);
                if (isLast)
                {
                    // All done
                    output.Add(this.currentMessage);
                    this.currentMessage = null;
                }
            }
            else
            {
                throw new MessageAggregationException($"Unexpected message {message}");
            }
        }
 /// <summary>
 /// 处理
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="byteBufferHolder"></param>
 /// <returns></returns>
 public abstract Task HandlerAsync(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder);
Beispiel #17
0
        /// <summary>
        /// 处理异常
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="byteBufferHolder"></param>
        /// <param name="exception"></param>
        /// <returns></returns>
        protected virtual async Task HandlerExceptionAsync(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder, Exception exception)
        {
            Dictionary <AsciiString, object> headers = HttpResponseHelper.GetDefaultHeaders("text/plain;charset=utf-8");
            IFullHttpResponse response = HttpResponseHelper.GetHttpResponse(HttpResponseStatus.InternalServerError, exception.Message, headers);

            IFilter[] globalFilters = _controllerBus.GetGlobalFilters();
            List <IExceptionFilter>      exceptionFilters      = globalFilters.OfType <IExceptionFilter>().ToList();
            List <IExceptionAsyncFilter> exceptionAsyncFilters = globalFilters.OfType <IExceptionAsyncFilter>().ToList();

            if (exceptionFilters.Count > 0 || exceptionAsyncFilters.Count > 0)
            {
                foreach (IExceptionFilter exceptionFilter in exceptionFilters)
                {
                    response = exceptionFilter.HandlerException(byteBufferHolder, exception);
                }
                foreach (IExceptionAsyncFilter exceptionFilter in exceptionAsyncFilters)
                {
                    response = await exceptionFilter.HandlerExceptionAsync(byteBufferHolder, exception);
                }
            }
            await SendHttpResponseAsync(ctx, byteBufferHolder, response);

            StopHandler();
        }
Beispiel #18
0
        private string FormatByteBufferHolder(IChannelHandlerContext ctx, string eventName, IByteBufferHolder msg)
        {
            string      str1          = ctx.Channel.ToString();
            string      str2          = msg.ToString();
            IByteBuffer content       = msg.Content;
            int         readableBytes = content.ReadableBytes;

            if (readableBytes == 0)
            {
                StringBuilder stringBuilder = new StringBuilder(str1.Length + 1 + eventName.Length + 2 + str2.Length + 4);
                string        str3          = str1;
                stringBuilder.Append(str3).Append(' ').Append(eventName).Append(", ").Append(str2).Append(", 0B");
                return(stringBuilder.ToString());
            }
            int           num  = readableBytes / 16 + (readableBytes % 15 == 0 ? 0 : 1) + 4;
            StringBuilder dump = new StringBuilder(str1.Length + 1 + eventName.Length + 2 + str2.Length + 2 + 10 + 1 + 2 + num * 80);
            string        str4 = str1;

            dump.Append(str4).Append(' ').Append(eventName).Append(": ").Append(str2).Append(", ").Append(readableBytes).Append('B').Append('\n');
            IByteBuffer buf = content;

            ByteBufferUtil.AppendPrettyHexDump(dump, buf);
            return(dump.ToString());
        }
Beispiel #19
0
        /// <summary>
        ///     Generates the default log message of the specified event whose argument is a <see cref="IByteBufferHolder" />.
        /// </summary>
        string FormatByteBufferHolder(IChannelHandlerContext ctx, string eventName, IByteBufferHolder msg)
        {
            string chStr = ctx.Channel.ToString();
            string msgStr = msg.ToString();
            IByteBuffer content = msg.Content;
            int length = content.ReadableBytes;
            if (length == 0)
            {
                var buf = new StringBuilder(chStr.Length + 1 + eventName.Length + 2 + msgStr.Length + 4);
                buf.Append(chStr).Append(' ').Append(eventName).Append(", ").Append(msgStr).Append(", 0B");
                return buf.ToString();
            }
            else
            {
                int rows = length / 16 + (length % 15 == 0 ? 0 : 1) + 4;
                var buf = new StringBuilder(
                    chStr.Length + 1 + eventName.Length + 2 + msgStr.Length + 2 + 10 + 1 + 2 + rows * 80);

                buf.Append(chStr).Append(' ').Append(eventName).Append(": ")
                    .Append(msgStr).Append(", ").Append(length).Append('B').Append('\n');
                ByteBufferUtil.AppendPrettyHexDump(buf, content);

                return buf.ToString();
            }
        }
Beispiel #20
0
        /// <summary>
        /// 发送Http返回
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="byteBufferHolder"></param>
        /// <param name="response"></param>
        protected virtual async Task SendHttpResponseAsync(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder, IFullHttpResponse response)
        {
            try
            {
                byteBufferHolder.Retain(0);
                if (ctx.Channel.Open)
                {
                    await ctx.Channel.WriteAndFlushAsync(response);

                    await ctx.CloseAsync();
                }
            }
            catch (Exception ex)
            {
                throw new MateralDotNettyException("发送HttpResponse失败", ex);
            }
        }
Beispiel #21
0
 public override async Task HandlerAsync(IChannelHandlerContext ctx, IByteBufferHolder byteBufferHolder)
 {
     if (byteBufferHolder is IFullHttpRequest request && request.Uri.Equals(WebSocketUrl, StringComparison.OrdinalIgnoreCase))
     {
         await ProtocolUpdateAsync(ctx, request);
     }
 protected abstract void HandleWebSocketFrame(IChannelHandlerContext ctx, IByteBufferHolder frame);