SpringBoot中的Reactive编程之Web请求的建立、接收、响应

前言

web请求连接建立

Netty的web服务端建立以后,具备了监听客户端连接的功能,在NioEventLoop的run方法中。且reactor-http-nio-1线程停留在strategy = select(curDeadlineNanos);方法中,但该线程没有阻塞。在这里插入图片描述
放开断点后,观察到线程reactor-http-nio-1没有再次进入到finally处的断点:
在这里插入图片描述
此时,前端输入请求地址:在这里插入图片描述
观察线程重新进入断点:
在这里插入图片描述
以上四副图中,揭示了链接发起到被Netty服务端建立和监听到的完整过程。

客户端与服务端的连接建立

这一过程实现了客户端到服务端的连接建立。会再次进入服务端时的Socket的注册过程。
在这里插入图片描述
判断此时NioServerSocketChannel的状态位,为16【SelectionKey.OP_ACCEPT】。表达的含义是此时从Selector中就绪的NioServerSocketChannel,正在接收客户端的连接。
在这里插入图片描述
unsafe.read()操作实现客户端与服务端的连接建立或者接收客户端的请求信息工作。通过SocketChannel ch = SocketUtils.accept(javaChannel());来获取到客户端的套接字SocketChannel对象,这里是不是与Socket编程一模一样?【但的确是用较少的线程和Selector实现了同样的Socket通信功能】。
在这里插入图片描述
这里注意一下,怎么实现客户端和服务端的连接对应关系?buf.add(new NioSocketChannel(this, ch));中的this指的是本次被Selector选择到的NioServerSocketChannel,以便服务端知道响应客户端通道。这一过程,是由pipeline.fireChannelRead(readBuf.get(i));来触发。

findContextInbound中获取到MASK_CHANNEL_READ的上下文,即:ServerBootstrapAcceptor。

	@Override
    @SuppressWarnings("unchecked")
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
   
        // 此msg其实就是NioSocketChannel
        final Channel child = (Channel) msg;
		// 此childHandler 其实就是 BootstrapInitializerHandler
		// 赋值的时机是在TcpServerBind的bind方法中
        child.pipeline().addLast(childHandler);

        setChannelOptions(child, childOptions, logger);
        setAttributes(child, childAttrs);

        try {
   
        	// 开启NioSocketChannel的注册流程,
        	// 此流程通NioServerSocketChannel流程一样
            childGroup.register(child).addListener(new ChannelFutureListener() {
   
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
   
                    if (!future.isSuccess()) {
   
                        forceClose(child, future.cause());
                    }
                }
            });
        } catch (Throwable t) {
   
            forceClose(child, t);
        }
    }

当执行到NioSocketChannelregister0时,由此方法下的pipeline.invokeHandlerAddedIfNeeded();开启NettyReactor的自定义的Handler:BootstrapInitializerHandler的初始化流程

	@Override
	protected void initChannel(Channel ch) {
   
		if (pipeline != null) {
   
			for (PipelineConfiguration pipelineConfiguration : pipeline) {
   
				// Http1Initializer的accept方法
				// 再向此channel的pipeline中添加两个Handler
				// 一个是HttpServerCodec
				// 一个是HttpTrafficHandler,在这个handler添加addLast过程中
				// 通过ctx.read()完成此channel的状态为由0【初始状态】变1【读状态】的操作
				pipelineConfiguration.consumer.accept(listener, ch);
			}
		}
		// 添加ChannelOperationsHandler
		ChannelOperations.addReactiveBridge(ch, opsFactory, listener);

		if (log.isDebugEnabled()) {
   
			log.debug(format(ch, "Initialized pipeline {}"), ch.pipeline().toString());
		}
	}

当完成对BootstrapInitializerHandler的初始化,在此channel的pipeline中删除其上下文:
在这里插入图片描述
接着完成safeSetSuccess()和fireChannelRegistered()这两个阶段,触发通道的激活pipeline.fireChannelActive();

	@Override
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值