Netty-10-WebSocket

Netty-10-WebSocket

前言

实例要求

  • Http 协议是无状态的,浏览器和服务器之间的请求只响应一次,下一次会重新创建连接
  • 要求 : 实现基于webSocket 的长连接全双工的交互
  • 改变Http 协议多次请求的约束,实现长连接,服务器可以发送消息给浏览器
  • 客户端浏览器和服务器端会相互感知,比如服务器关闭了,浏览器会感知,同样浏览器关闭了,服务器会感知

1. 启动器代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public static void main(String[] args) throws InterruptedException {
NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//因为是基于Http协议,所以要使用Http的编码和解码器
pipeline.addLast(new HttpServerCodec());
//是以块方式写,添加ChunkedWriter处理器
pipeline.addLast(new ChunkedWriteHandler());
/**
* 1、http数据在传输过程中是分裂的,HttpObjectAggregator就可以将多个段聚合
* 2、这就是为什么,当浏览器发送大量数据时,就会发出多次http请求
*/
pipeline.addLast(new HttpObjectAggregator(8192));

/**
* 1、对于websocket,它的数据是以帧的形式传递的
* 2、可以看到 WebsocketFrame 下面有六个子类
* 3、浏览器请求时:ws://localhost:7000/hello 表示请求的uri
* 4、WebSocketServerProtocolHandler 核心功能是将 http 协议升级为 ws 协议,保持长连接
* 5、从Http协议升级到Websocket协议,是通过StatusCode 101(Switching Protocols)来切换的。
*/
pipeline.addLast(new WebSocketServerProtocolHandler("/hello"));

//自定义Handler,处理业务逻辑
pipeline.addLast(new MyTextWebSocketFrameHandler());
}
});
ChannelFuture sync = serverBootstrap.bind(7000).sync();
sync.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}

2 . 案例总结

  1. 创建启动类
  • 首先初始化两个NioEventLoopGroup。其中BossGroup一般设置线程为1
  • 初始化一个ServerBootStrap类。并调用它设置很多参数。
    • group():服务端设置两个Group,客户端设置一个Group
    • channel():服务端传入NioServerSocketChannel,客户端传入NioSocketChannel
    • option():服务端给BossGroup设置SO_BACKLOG任务队列大小
    • childOption():服务端给WorkerGroup设置连接SO_KEEPALIVE保持连接状态
    • handler():服务端给BossGroup设置Handler,客户端设置Handler
    • childHandler():服务端给WorkerGroup设置Handler。
  • 通过BootStrap去绑定端口,监听关闭事件。设置为异步拿到ChannelFuture对象
  1. Handler 处理逻辑
  • SimpleChannelInboundHandler
    • 可以继承它来处理很多通信。经过上面几个案例推敲,一般写自己的Handler继承它就可以了
  • ChannelInboundHandlerAdapter
    • 这个是上一个的父类,我们在心跳检测的时候通过继承它的userEventTriggered去判断连接状态
    • 其实通过上面那个simple也可以继承这个trigger
  • IdleStateHandler
    • 在心跳检测时我们要通过这个Handler去触发上面的trigger
  • HttpServerCodec
    • 提供好的用于Http编码解码,一般用于Http请求
  • ChunkedWriteHandler
    • 提供好的Handler,以块方式写,添加ChunkedWriter处理器
    • 我搜了一下,它一般用于发送大文件。这个东西使我们在Websocket的时候用的。
  • HttpObjectAggregator
    • 它会将http数据聚合在一起发送
  • WebSocketServerProtocolHandler
    • 传入ws路径,将Http协议升级成为ws协议
  1. netty 中通信数据实体
  • TextWebSocketFrame
    • 这是我们在websocket连接的时候用的,它表示一个文本帧,是websocket进行通信的数据形式
  • HttpObject
    • 这是我们在建立Http连接的时候用到的,可以将它转换成一个HttpRequest
  1. Handler 常用方法
方法名 介绍
channelRead0(ChannelHandlerContext channelHandlerContext, T t) 读取数据,并进行消息转发
handlerAdded(ChannelHandlerContext ctx) 连接建立,一旦建立连接,就第一个被执行
channelActive(ChannelHandlerContext ctx) 表示 channel 处于活动状态,提示 xxx 上线
channelInactive(ChannelHandlerContext ctx) 表示 channel 处于不活动状态,提示 xxx 离线
handlerRemoved(ChannelHandlerContext ctx) 表示 channel 断开连接,将xx客户离开信息推送给当前在线客户
exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 出现错误如何进行处理
userEventTriggered(ChannelHandlerContext ctx, Object evt) 事件触发器,通过判断evt的类型去判断发生了什么事件,再通过里面的属性判断事件发生的类型。我们在IdleStateHandler后面加上一个触发器,可以检测心跳。

本文档整理自 尚硅谷韩顺平Netty 相关课程。

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信