예제 #1
0
        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();
                }
            }
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
     }
 }
예제 #6
0
        public void UpgradeFrom(IChannelHandlerContext ctx)
        {
            IChannelPipeline p = ctx.Pipeline;

            _ = p.Remove(this);
        }