• netty源码学习—课堂1


    demo示例

    Client 

    Server

    Nio模型

    model-1

     

    model-2

     

    model-3

     

     

    model-netty

    Boss

    Worker

     

    Channel设计

     

     

     场景

    connect->read->write->close

    interestOps, selectionKey

    OP_READ可读可写. neither read nor write operation has been suspended.

    OP_WRITE不可读不可写. both has been suspended.

    OP_READ_WRITE 可读不可写. write operation has been suspended.

    OP_NONE 不可读可写. read operation has been suspended.

     

     

    Pipeline设计

    upstream:

    l  HutuDecoder

    l  messageReceived, exceptionCaught, channelOpen, channelClosed, channelBound, channelUnbound, channelConnected, writeComplte, channelDisconnected, changeInterestChanged

    downstream:

    l  HutuEncoder

    l  write, bind, unbind, connect, disconnect, close

    ByteBuffer设计

    to be continued…

    网摘:分析Netty工作流程

    下面以Netty中Echo的例子进行流程跟踪,并简要的

    服务器启动->客户端连接-> 服务器处理连接-> 服务器处理客户端数据<-> 客户端处理服务器数据

     

    1:客户端连接:

     

    我们直接看这行代码:

    bootstrap.connect(new InetSocketAddress(host, port));

    通过帮助类ClientBootstrap来连接服务器。

    Debug源码进去发现最后是某个Channel类进行connect操作。 

    而这个Channel是如何来的呢?其实是从前面的 ChannelFactory和ChannelPipelineFactory得到的。 

    Channel.connect-> AbstractChannel.connect->Channels.connect(…); 

    Channels是Channel的帮助类,封装一些常用的操作。在封装操作时,基本都是触发事件。

    这里发起一个connectd的Downstream的事件。

     

    所有的事件都是丢给ChannelPipeline进行管理,ChannelPipeline使用了责任链模式来将事件传送给注册到Pipeline中的ChannelHandler,由ChannelHandler进行处理。如果遍历了所有的ChannelHandler后则交给ChannelSink进行处理,ChannelSink根据不同的事件进行不同的处理,对于connect事件,ChannelSink发送连接操作后则将该Channel注册到NioWorker中,以后的任何事件都通过NioWorker(封装selector的操作)来进行处理。

     

    客户端连接的流程为:

    ClientBootstrap.connect –>Channel.connect->

    AbstractChannel.connect->Channels.connect(…)

             -> 发送connect事件-> ChannelSink->发起实际的连接操作->将Channel注册给Nioworker

     

    2:服务器启动:

             bootstrap.bind(…)-> 触发ServerSocketChannel.open()的事件

    ->捕捉open事件,channel.bind-> Channels.bind(…) -> 发起bind命令-> PipelineSink进行处理-> 使用socket进行bind,等待连接事件。

     

    3: 服务器处理连接

       服务器启动后,NioServerSocketPipelineSink.Boss.run()在监听accept事件-> 捕捉到accept事件 -> 将NioWorker进行注册NioSocketChannel

    -> 向java.nio.SocketChannel注册op_read的监听。

     

    4:客户端开始向服务器发送数据:

        当客户端连接Server后,就会发起Connected的upstream事件->通过Pipeline进行处理-> SimpleChannelUpstreamHandler.handleUpstream()->

    EchoClientHandler.channelConnected()

     

    5:服务器端接收并处理数据

    接收数据:

        NioWorker.run()->nioworker. processSelectedKeys()->

    Nioworker. Read()将从SocketChannel读取的数据封装成

    ChannelBuffer ->发送upstream事件:fireMessageReceived(channel,buffer) –> 由注册到Pipeline中的Hanlder进行处理: EchoServerHandler. messageReceived(…)

     

    发送数据:

    e.getChannel().write(e.getMessage());->Channels.write()->

    发起downstream事件-> NioServerSocketPipelineSink. handleAcceptedSocket()将向外写的事件放入Channel中,然后通过NioWorker.writeFromUserCode()进行发送。

    6:客户端:客户端的流程和服务器端类似。

    总结:

    1: Netty将操作封装成事件,比如: 发起连接时,产生connect的downstream事件。连接完毕后,产生upstream的connect事件。 

    2:所有的事件都是放入Pipeline进行传送,传送的过程中可能被注册到pipeline中的Handler进行处理

    3:在Pipeline传送完后,都必须都通ChannelSink进行处理。Sink默认处理了琐碎的操作,必须连接、读写等等。 

    4:Channels:几乎所有的操作都能在这里找到,当然Channels一般是发送事件

    5:NioWorker: 处理IO事件的核心类,并承担了分发的责任。

  • 相关阅读:
    Graphics Card Notes | 烧卡日记(显卡常识笔记)
    PyCharm Notes | PyCharm 使用笔记(远程访问服务器code配置指南)
    Python Notes | Python 备忘笔记
    conda清华镜像(TUNA)使用指南
    vim 操作手册
    WebNotes(PHP、css、JavaScript等)
    Linux网络配置:设置IP地址、网关DNS、主机名
    Linux挂载:VMware tools for Linux安装
    Linux磁盘分区的理解
    什么是Python?Python的设计哲学?如何获取/升级Python?
  • 原文地址:https://www.cnblogs.com/alipayhutu/p/2781438.html
Copyright © 2020-2023  润新知