public sealed override void ChannelRegistered(IChannelHandlerContext context) { IChannelPipeline pipeline = context.Channel.Pipeline; bool success = false; try { this.InitChannel((T)context.Channel); pipeline.Remove(this); context.FireChannelRegistered(); success = true; } catch (Exception ex) { Logger.Warn("Failed to initialize a channel. Closing: " + context.Channel, ex); } finally { if (pipeline.Context(this) != null) { pipeline.Remove(this); } if (!success) { context.CloseAsync(); } } }
/// <summary> /// Performs the opening handshake /// When call this method you <c>MUST NOT</c> retain the <see cref="IFullHttpRequest"/> which is passed in. /// </summary> /// <param name="channel">Channel</param> /// <param name="req">HTTP Request</param> /// <param name="responseHeaders">Extra headers to add to the handshake response or <code>null</code> if no extra headers should be added</param> /// <param name="completion">the <see cref="IPromise"/> to be notified when the opening handshake is done</param> public void Handshake(IChannel channel, IFullHttpRequest req, HttpHeaders responseHeaders, IPromise completion) { #if DEBUG if (Logger.DebugEnabled) { Logger.WebSocketVersionServerHandshake(channel, _version); } #endif IFullHttpResponse response = NewHandshakeResponse(req, responseHeaders); IChannelPipeline p = channel.Pipeline; if (p.Get <HttpObjectAggregator>() is object) { _ = p.Remove <HttpObjectAggregator>(); } if (p.Get <HttpContentCompressor>() is object) { _ = p.Remove <HttpContentCompressor>(); } if (p.Get <CorsHandler>() is object) { _ = p.Remove <CorsHandler>(); } if (p.Get <HttpServerExpectContinueHandler>() is object) { _ = p.Remove <HttpServerExpectContinueHandler>(); } if (p.Get <HttpServerKeepAliveHandler>() is object) { _ = p.Remove <HttpServerKeepAliveHandler>(); } IChannelHandlerContext ctx = p.Context <HttpRequestDecoder>(); string encoderName; if (ctx is null) { // this means the user use an HttpServerCodec ctx = p.Context <HttpServerCodec>(); if (ctx is null) { _ = completion.TrySetException(ThrowHelper.GetInvalidOperationException_NoHttpDecoderAndServerCodec()); return; } encoderName = ctx.Name; _ = p.AddBefore(encoderName, "wsencoder", NewWebSocketEncoder()); _ = p.AddBefore(encoderName, "wsdecoder", NewWebsocketDecoder()); } else { _ = p.Replace(ctx.Name, "wsdecoder", NewWebsocketDecoder()); encoderName = p.Context <HttpResponseEncoder>().Name; _ = p.AddBefore(encoderName, "wsencoder", NewWebSocketEncoder()); } _ = channel.WriteAndFlushAsync(response).ContinueWith(RemoveHandlerAfterWriteAction, (completion, p, encoderName), TaskContinuationOptions.ExecuteSynchronously); }
public void Handshake(IChannel channel, IFullHttpRequest req, HttpHeaders responseHeaders, TaskCompletionSource completion) { if (Logger.DebugEnabled) { Logger.Debug("{} WebSocket version {} server handshake", channel, this.version); } IFullHttpResponse response = this.NewHandshakeResponse(req, responseHeaders); IChannelPipeline p = channel.Pipeline; if (p.Get <HttpObjectAggregator>() != null) { p.Remove <HttpObjectAggregator>(); } if (p.Get <HttpContentCompressor>() != null) { p.Remove <HttpContentCompressor>(); } IChannelHandlerContext ctx = p.Context <HttpRequestDecoder>(); string encoderName; if (ctx == null) { // this means the user use a HttpServerCodec ctx = p.Context <HttpServerCodec>(); if (ctx == null) { completion.TrySetException(new InvalidOperationException("No HttpDecoder and no HttpServerCodec in the pipeline")); return; } p.AddBefore(ctx.Name, "wsdecoder", this.NewWebsocketDecoder()); p.AddBefore(ctx.Name, "wsencoder", this.NewWebSocketEncoder()); encoderName = ctx.Name; } else { p.Replace(ctx.Name, "wsdecoder", this.NewWebsocketDecoder()); encoderName = p.Context <HttpResponseEncoder>().Name; p.AddBefore(encoderName, "wsencoder", this.NewWebSocketEncoder()); } channel.WriteAndFlushAsync(response).ContinueWith(t => { if (t.Status == TaskStatus.RanToCompletion) { p.Remove(encoderName); completion.TryComplete(); } else { completion.TrySetException(t.Exception); } }); }
/// <summary> /// Populates the channel pipeline in order to upgrade a connection to WebSocket. /// </summary> public static void populateWSPipelineForHandshake(IChannel ch, IChannelHandler wsHandshakeHandler) { IChannelPipeline p = ch.Pipeline; /* * Note: since the channel pipeline was filled by populateHttpPipeline(), * we must remove the HTTP user-defined handler before of upgrading the channel */ p.Remove(READER_KEY); p.AddLast(new HttpObjectAggregator(8192)); p.AddLast(WebSocketClientCompressionHandler.Instance); p.AddLast(wsHandshakeHandler); }
void Remove(IChannelHandlerContext ctx) { try { IChannelPipeline pipeline = ctx.Channel.Pipeline; if (pipeline.Context(this) != null) { pipeline.Remove(this); } } finally { initMap.TryRemove(ctx, out bool removed); } }
public void UpgradeFrom(IChannelHandlerContext ctx) { IChannelPipeline p = ctx.Pipeline; _ = p.Remove(this); }