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())); }
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; }
public int Size(object msg) { return(msg switch { IByteBuffer byteBuffer => byteBuffer.ReadableBytes, IByteBufferHolder byteBufferHolder => byteBufferHolder.Content.ReadableBytes, IFileRegion fileRegion => 0, _ => _unknownSize, });
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; } }
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); } }
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); } }
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); } }
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); } }
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);
/// <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(); }
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()); }
/// <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(); } }
/// <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); } }
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);