Netty程序员

整理 Netty WebSocket

2017-04-19  本文已影响2098人  58bc06151329

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

  1. Netty是针对Java Nio(非阻塞式)Java网络API,隐藏背后复杂性(可靠、可扩展的事件处理器处理和调度数据,并尽可能的保证有效、正确性和安全性),提供易于使用的服务器\客户端网络编程框架。

  2. Channel是Nio的基本结构,是作为数据传入和传出的运输工具。

  3. Callback是一个回调简单方法,Netty内部使用回调处理事件。

例如:

public class ChannelHandlerAdapter implements ChannelHandler
public void channelActive(ChannelHandlerContext ctx) throws Exception 
{ 
    ctx.fireChannelActive();
}

一旦一个新的连接建立,则调用channelActive方法。

  1. 除了回调方式,还可以使用Future,提供另外一种通知应用操作方式。Netty提供了ChannelFuture,执行异步操作。

例如:

ChannelFuture future = channel.connect(new InetSocketAddress("192.168.96.103", 25));
future.addListener(new ChannelFutureListener() { 
    public void operationComplete(ChannelFuture future) { 
        if (future.isSuccess()) { 
            ByteBuf buffer = Unpooled.copiedBuffer("连接成功!", Charset.defaultCharset());                      
            ChannelFuture wf = future.channel().writeAndFlush(buffer); 
        } else { 
            Throwable cause = future.cause(); cause.printStackTrace(); 
        } 
    }
})
  1. Netty使用不同的事件更改或操作状态,每一个事件都可以定义一个事件处理器,ChannelHandler将各种程序处理器进行了抽象,实际就是响应对应事件的回调。

  2. ChannelFuture使用事件和future本身,创建具有Netty特性的消费者。

  3. 每个Channel都有关联的ChannelPipeline,代表ChannelHandler实例的链,如果一个Netty Handler不处理exceptionCaught,将传递给下一个ChannelHandler实例,因此至少需要有一个覆盖了exceptionCaught的ChannelHandler。

  4. 引导服务器/客户端Socket的过程如下:

Bootstrap

引导类,应用程序网络层配置的容器。

Channel

一个Socket连接,封装IO基本操作。

ChannelHandler

支持很多协议,提供数据处理的容器。

ChannelPipeline

提供Handler链的容器。

EventLoop

用于处理Channel的I/O操作,一个EventLoop处理多个Channel,一个EventLoopGroup包含多个EventLoop。

ChannelFuture

Netty的所有I/O操作都是异步的,无法立即返回操作结构,可以通过ChannelFuture注册事件,当操作完成时,获取事件通知。
  1. 服务器ServerBootstrap,需要两个EventLoopGroup,一个是单例的,负责监测本地端口,并且轮询客户端是否建立连接(创建Channel),一个负责接收处理Channel的消息(分配一个EventLoop给Channel)。

  2. ChannelHandler分为入站(ChannelInHandler)和出站(ChannelOutHandler)两种,在引导程序的时候,被加入ChannelPipeline,被增加进入的顺序,决定了执行的顺序。
    入站时,从ChannelPipeline的第一个ChannelInHandler执行到最后一个。出站时,从ChannelPipeline的最后一个ChannelOutHandler执行到第一个。在ChannelHandler之间传递的是ChannelHandlerContext,可以看作是ChannelHandler与ChannelPipeline之间的绑定关系。通过ChannelHandlerContext.channel().writeAndFlush写入消息,是到达ChannelPipeline尾部才写入消息,而ChannelHandlerContext.writeAndFlush写入消息,是到达下一个ChannelInHandler就写入消息。

SimpleChannelboundHandler

常见处理器,只需要继承SimpleChannelboundHandler即可。

选择器参数

方法名称 描述
OP_ACCEPT 有新连接时通知
OP_CONNECT 连接完成后通知
OP_READ 准备好读取数据时通知
OP_WRITE 准备好写入数据时通知

Channel的生命周期

状态 描述
channelActive channel变为激活状态,连接到远程主机,可以收发消息。
channelInactive channel处于非激活状态,没有连接到远程主机
channelRegistered channel注册到一个EventLoop。
channelUnregistered channel已经创建,但是未注册到一个EventLoop。
messageReceived 接收消息时调用。

Handler的生命周期

状态 描述
handlerAdded 当ChannelHandler增加到ChannelPipeline。
handlerRemoved 当ChannelHandler移除ChannelPipeline。
exceptionCaught 当ChannelPipeline抛出异常时调用。
  1. ChannelPipeline可以动态的添加和删除Handler。可以通过ChannelHandlerContext获得关联的pipeline,从而实现一些动态加载Handler效果。

  2. ChannelHandler可以属于多个ChannelPipeline,但是必须添加@Sharable注解,表示可以共享使用,否则会抛出异常。并且要保证ChannelHandler是线程安全的。这种效果一般是为了实现共享ChannelHandler以此来实现跨多个渠道收集统计数据。

实现SSL/TLS加密解密的SslHandler

大多数情况下,SslHandler都作为ChannelPipeline的第一个Handler。

实现HTTP消息聚合

增加HTTP消息编码器,HttpServerCodec,消息聚合HttpObjectAggregator(512)。最大值为512kb。

实现HTTPS

只需增加SslHandler。

实现WebSocket

名称 描述
BinaryWebSocketFrame 二进制数据。
TextWebSocketFrame 文本数据。
ContinuationWebSocketFrame 超大文本或者二进制数据。

空闲连接以及超时

ChunkedWriteHandler

处理大数据传输,支持异步写大数据流,不引起高内存消耗。

引导客户端和无连接协议

名称 描述
group 设置EventLoopGroup处理所有的Channel的事件。
channel 定义Channel处理方式,默认支持4种定义,NIO、OIO、Local和Embedded
option 应用于新创建的Channel,作用于ChannelConfig,创建连接后无效果。
attr 设置属性,创建连接后无效果。
handler 添加Handler到ChannelPipeline,初始化连接时执行。
clone 拷贝Bootstrap属性。
connect 连接到远端,参数IP(域名)和端口号,返回一个ChannelFuture。

EventLoopGroup与Channel需要保持一致的兼容性,否则会抛出IIIegalStateException异常。

引导服务器

名称 描述
group 设置两个,一个EventLoopGroup处理监听端口,一个EventLoopGroup处理所有的Channel的事件。
channel 定义Channel处理方式,默认支持4种定义,NIO、OIO、Local和Embedded
option 应用于新创建的Channel,作用于ChannelConfig,创建连接后无效果。
childOption 应用于已接收的Channel,作用于ChannelConfig。
attr 设置属性,创建连接后无效果。
childAttr 设置属性,作用于已接收的Channel。
handler 添加Handler到ChannelPipeline,初始化连接时执行。
ChildHandler 添加Handler到ChannelPipeline,建立连接后执行。
clone 拷贝Bootstrap属性。
bind 绑定本地端口,参数端口号,返回一个ChannelFuture。

可以通过group.shutdownGracefully()实现优雅的关闭。

WebSocketServerProtocolHandler

处理除TextWebSocketFrame以外的其他类型帧。

WebSocket的初始化流程

名称 职责
HttpServerCodec Http编码器。
HttpObjectAggregator Http消息聚合。
ChunkedWriteHandler 大数据处理,主要针对SSL加密解密。
HttpRequestHandler 用户自定义处理ws请求。
WebSocketServerProtocolHandler 处理除TextWebSocketFrame以外的消息事件。所有规定的WebSocket帧类型。
TextWebSocketFrameHandler 用户自定义处理TextWebSocketFrame的消息事件。

在ChannelPipeline执行的过程中,会替换或者删除Handler,当WebSocket执行完成后剩余WebSocketFrameDecoder、WebSocketFrameEncoder、WebSocketServerProtocolHandler和TextWebSocketFrameHandler四个Handler。

上一篇下一篇

猜你喜欢

热点阅读