当前位置: 首页 > news >正文

Netty从0到1系列之内置Handler【下】

文章目录

  • Netty内置Hanlders【下】
  • 二、日志与调试类 Handler
    • 2.1 LoggingHandler
      • 2.1.1 概述
      • 2.1.2 示例代码
      • 2.1.3 流程
  • 三、连接管理类 Handler
    • 3.1 IdleStateHandler
      • 3.1.1 概述
      • 3.1.2 示例代码
      • 3.1.3 流程
  • 四、安全类 Handler
    • 4.1 SslHandler
      • 4.1.1 概述
      • 4.1.2 简化后的示例代码
      • 4.1.3 流程
  • 五、流量控制类 Handler
    • 5.1 ChannelTrafficShapingHandler
      • 5.1.1 概述
      • 5.1.2 示例代码
      • 5.1.3 处理流程
    • 5.2 FlowControlHandler
      • 5.2.1 概述
      • 5.2.2 示例代码
    • 5.3 WriteBufferWaterMark
      • 5.3.1 概述
      • 5.4.2 示例代码
  • 六、HTTP相关Handler
    • 6.1 HttpServerCodec
      • 6.1.1 概述
      • 6.1.2 示例代码
      • 6.1.3 流程
    • 6.2 HttpClientCodec
      • 6.2.1 概述
      • 6.2.2 示例代码
    • 6.3 HttpObjectAggregator
      • 6.3.1 概述
      • 6.3.2 示例代码
  • 七、WebSocket 相关 Handler
    • 7.1 WebSocketServerProtocolHandler
      • 7.1.1 概述
      • 7.1.2 示例代码
      • 7.1.3 流程处理
    • 7.2 WebSocketClientProtocolHandler
      • 7.2.1 概述
      • 7.2.2 示例代码
  • 八、Handler选择指南
    • 8.1 根据协议选择
    • 8.2 根据功能选择
    • 8.3 性能考虑


推荐阅读:

【01】Netty从0到1系列之I/O模型
【02】Netty从0到1系列之NIO
【03】Netty从0到1系列之Selector
【04】Netty从0到1系列之Channel
【05】Netty从0到1系列之Buffer(上)
【06】Netty从0到1系列之Buffer(下)
【07】Netty从0到1系列之零拷贝技术
【08】Netty从0到1系列之整体架构、入门程序
【09】Netty从0到1系列之EventLoop
【10】Netty从0到1系列之EventLoopGroup
【11】Netty从0到1系列之Future
【12】Netty从0到1系列之Promise
【13】Netty从0到1系列之Netty Channel
【14】Netty从0到1系列之ChannelFuture
【15】Netty从0到1系列之CloseFuture
【16】Netty从0到1系列之Netty Handler
【17】Netty从0到1系列之Netty Pipeline【上】
【18】Netty从0到1系列之Netty Pipeline【下】
【19】Netty从0到1系列之Netty ByteBuf【上】
【20】Netty从0到1系列之Netty ByteBuf【中】
【21】Netty从0到1系列之Netty ByteBuf【下】
【22】Netty从0到1系列之Netty 逻辑架构【上】
【23】Netty从0到1系列之Netty 逻辑架构【下】
【24】Netty从0到1系列之Netty 启动细节分析
【25】Netty从0到1系列之Netty 线程模型【上】
【26】Netty从0到1系列之Netty 线程模型【下】
【27】Netty从0到1系列之Netty ChannelPipeline
【28】Netty从0到1系列之Netty ChannelHandler
【29】Netty从0到1系列之Netty拆包、粘包【1】
【30】Netty从0到1系列之Netty拆包、粘包【2】
【31】Netty从0到1系列之Netty拆包、粘包【3】
【32】Netty从0到1系列之Netty拆包、粘包【4】
【33】Netty从0到1系列之Netty拆包、粘包【5】
【34】Netty从0到1系列之动态从内存分配】
【35】Netty从0到1系列之writeAndFlush原理分析】
【36】Netty从0到1系列之Netty内存管理【上】】
【37】Netty从0到1系列之Netty内存管理【下】】
【38】Netty从0到1系列之Netty内存管理【1】】
【39】Netty从0到1系列之Netty内存管理【2】】
【40】Netty从0到1系列之Netty内存管理【3】】
【41】Netty从0到1系列之Netty内存管理【4】】
【42】Netty从0到1系列之Netty零拷贝技术】
【43】Netty从0到1系列之内置Handler【上】】


Netty内置Hanlders【下】

二、日志与调试类 Handler

2.1 LoggingHandler

2.1.1 概述

✅ 特点:

  • 打印入站/出站事件日志(连接、读写、异常等)
  • 可配置日志级别(默认 INFO)
  • 无侵入调试神器

🎯 应用场景:

  • 开发调试、线上问题追踪、协议分析

2.1.2 示例代码

✅ 1. LoggingServerInitializer

package cn.tcmeta.codec.logger;import cn.tcmeta.codec.text.TextEchoHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;public class LoggingServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) {ChannelPipeline p = ch.pipeline();// 添加日志处理器(SLF4J 日志,日志级别 DEBUG)p.addFirst("loggingHandler", new LoggingHandler(LogLevel.DEBUG));p.addLast("stringDecoder", new StringDecoder());p.addLast("stringEncoder", new StringEncoder());p.addLast("echoHandler", new TextEchoHandler());}
}

✅ 2. 测试示例
在这里插入图片描述

服务器端日志输出:
在这里插入图片描述

2.1.3 流程

事件发生
LoggingHandler
打印日志到控制台/文件
继续传递给下一个Handler

三、连接管理类 Handler

3.1 IdleStateHandler

3.1.1 概述

✅ 特点:

  • 检测读空闲、写空闲、全空闲
  • 触发 userEventTriggered 事件
  • 常用于心跳机制

🎯 应用场景:

  • 心跳保活、连接超时断开、防 DoS

3.1.2 示例代码

✅ 1. HeartbeatServerInitializer

package cn.tcmeta.codec.states;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;import java.util.concurrent.TimeUnit;public class HeartbeatServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) {ChannelPipeline p = ch.pipeline();// 读空闲5秒、写空闲7秒、全空闲10秒p.addLast("idleStateHandler", new IdleStateHandler(5, 7, 10, TimeUnit.SECONDS));p.addLast("stringDecoder", new StringDecoder());p.addLast("stringEncoder", new StringEncoder());p.addLast("heartbeatHandler", new HeartbeatHandler());}
}

✅ 2. HeartbeatHandler

package cn.tcmeta.codec.states;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;public class HeartbeatHandler extends ChannelInboundHandlerAdapter {@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) {if (evt instanceof IdleStateEvent e) {switch (e.state()) {case READER_IDLE:System.out.println("读空闲,发送心跳请求...");ctx.writeAndFlush("PING");break;case WRITER_IDLE:System.out.println("写空闲,主动发心跳...");ctx.writeAndFlush("PING");break;case ALL_IDLE:System.out.println("连接空闲太久,关闭连接");ctx.close();break;}}}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {String s = (String) msg;if ("PONG".equals(s)) {System.out.println("收到心跳响应");} else {ctx.fireChannelRead(msg); // 非心跳消息交给后续处理器}}
}

✅ 3. 测试
在这里插入图片描述

  • 服务器端日志输出

在这里插入图片描述

3.1.3 流程

读空闲
写空闲
全空闲
连接建立
IdleStateHandler开始计时
是否超时?
触发READER_IDLE事件
触发WRITER_IDLE事件
触发ALL_IDLE事件
发送PING
关闭连接

四、安全类 Handler

4.1 SslHandler

4.1.1 概述

✅ 特点:

  • 提供 SSL/TLS 加密通信
  • 支持双向认证、证书校验
  • 基于 JDK SSL 或 OpenSSL(性能更好)

🎯 应用场景:

  • HTTPS、WSS、安全通信通道

4.1.2 简化后的示例代码

/*** SSL处理器示例*/
public class SslHandlerExample {/*** 创建SSL上下文*/public static SslContext createSslContext(boolean isServer) throws SSLException {if (isServer) {// 服务器SSL上下文return SslContextBuilder.forServer(new File("server.crt"),     // 服务器证书new File("server.key")      // 服务器私钥).build();} else {// 客户端SSL上下文return SslContextBuilder.forClient().trustManager(new File("ca.crt"))  // 受信任的CA证书.build();}}/*** 配置HTTPS服务器管道*/public static void configureHttpsServerPipeline(ChannelPipeline pipeline) throws SSLException {// 创建SSL上下文SslContext sslContext = createSslContext(true);// 添加SSL处理器pipeline.addLast("ssl", sslContext.newHandler(pipeline.channel().alloc()));// HTTP编解码器pipeline.addLast("httpCodec", new HttpServerCodec());// HTTP对象聚合器pipeline.addLast("httpAggregator", new HttpObjectAggregator(65536));// HTTP请求处理器pipeline.addLast("httpHandler", new SimpleHttpHandler());}/*** 配置HTTPS客户端管道*/public static void configureHttpsClientPipeline(ChannelPipeline pipeline) throws SSLException {// 创建SSL上下文SslContext sslContext = createSslContext(false);// 添加SSL处理器pipeline.addLast("ssl", sslContext.newHandler(pipeline.channel().alloc()));// HTTP编解码器pipeline.addLast("httpCodec", new HttpClientCodec());// HTTP对象聚合器pipeline.addLast("httpAggregator", new HttpObjectAggregator(65536));// HTTP响应处理器pipeline.addLast("httpHandler", new SimpleHttpResponseHandler());}/*** SSL握手监听示例*/public static void addSslHandshakeListener(ChannelPipeline pipeline) {SslHandler sslHandler = (SslHandler) pipeline.get("ssl");// 添加握手完成监听器sslHandler.handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() {@Overridepublic void operationComplete(Future<Channel> future) {if (future.isSuccess()) {System.out.println("SSL握手成功");// 握手成功后可以开始发送加密数据} else {System.err.println("SSL握手失败: " + future.cause());future.cause().printStackTrace();}}});}
}

4.1.3 流程

明文字节流
SslHandler
加密后传输
网络
SslHandler
解密为明文
业务处理器

五、流量控制类 Handler

5.1 ChannelTrafficShapingHandler

5.1.1 概述

✅ 特点:

  • 控制全局或单 Channel 的读写速率
  • 支持写暂停、排队、延迟发送
  • 防止服务被突发流量压垮

🎯 应用场景:

  • API 网关、文件服务器、防止 DDOS

5.1.2 示例代码

public class TrafficShapedServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) {ChannelPipeline p = ch.pipeline();// 限制:写速度 1KB/s,读速度 2KB/s,检查间隔 1sp.addFirst("trafficShaper", new ChannelTrafficShapingHandler(2048, 1024, 1000));p.addLast("stringDecoder", new StringDecoder());p.addLast("stringEncoder", new StringEncoder());p.addLast("echoHandler", new TextEchoHandler());}
}

5.1.3 处理流程

高速写入数据
ChannelTrafficShapingHandler
是否超速?
排队/延迟发送
立即发送
按速率发送

5.2 FlowControlHandler

5.2.1 概述

特点:

  • 流量控制处理器
  • 防止缓冲区溢出
  • 控制消息处理速率

应用场景:

  • 高并发场景下的流量控制
  • 防止系统过载
  • 控制资源使用

5.2.2 示例代码

/*** 流量控制处理器示例*/
public class FlowControlHandlerExample {/*** 配置带流量控制的服务器管道*/public static void configureFlowControlPipeline(ChannelPipeline pipeline) {// 添加流量控制处理器pipeline.addLast("flowControl", new FlowControlHandler());// 业务处理器pipeline.addLast("businessHandler", new BusinessHandler());}/*** 业务处理器(模拟耗时操作)*/static class BusinessHandler extends SimpleChannelInboundHandler<String> {private final AtomicInteger concurrentRequests = new AtomicInteger(0);private final int maxConcurrentRequests = 100;@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) {// 检查并发请求数int current = concurrentRequests.incrementAndGet();if (current > maxConcurrentRequests) {concurrentRequests.decrementAndGet();System.err.println("超过最大并发请求数,拒绝请求: " + msg);ctx.writeAndFlush("服务器繁忙,请稍后再试");return;}try {// 模拟耗时处理Thread.sleep(100);// 处理请求String response = "处理结果: " + msg.toUpperCase();ctx.writeAndFlush(response);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {concurrentRequests.decrementAndGet();}}}
}

5.3 WriteBufferWaterMark

5.3.1 概述

特点:

  • 写缓冲区水位标记
  • 控制写操作的流量
  • 防止内存溢出

应用场景:

  • 控制大文件传输
  • 防止写缓冲区溢出
  • 平衡网络传输速度

5.4.2 示例代码

/*** 写缓冲区水位标记示例*/
public class WriteBufferWaterMarkExample {/*** 配置写缓冲区水位标记*/public static void configureWriteBufferWaterMark(ServerBootstrap bootstrap) {bootstrap.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(32 * 1024,      // 低水位:32KB64 * 1024       // 高水位:64KB));}/*** 监听写状态变化*/public static void addWriteStateListener(Channel channel) {channel.pipeline().addFirst("writeStateMonitor", new ChannelDuplexHandler() {@Overridepublic void channelWritabilityChanged(ChannelHandlerContext ctx) {if (ctx.channel().isWritable()) {System.out.println("通道可写,可以继续发送数据");} else {System.out.println("通道不可写,暂停发送数据");}ctx.fireChannelWritabilityChanged();}});}/*** 可写的业务处理器*/static class WritableBusinessHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {// 检查通道是否可写if (ctx.channel().isWritable()) {// 发送大文件sendLargeFile(ctx);} else {// 通道不可写时,等待可写事件ctx.channel().eventLoop().execute(() -> {ctx.pipeline().fireUserEventTriggered("SEND_LARGE_FILE");});}}private void sendLargeFile(ChannelHandlerContext ctx) {// 模拟发送大文件for (int i = 0; i < 1000; i++) {ByteBuf data = Unpooled.copiedBuffer("Chunk " + i + "\n", StandardCharsets.UTF_8);ctx.write(data);// 定期刷新缓冲区if (i % 10 == 0) {ctx.flush();}}ctx.flush();}}
}

六、HTTP相关Handler

6.1 HttpServerCodec

6.1.1 概述

✅ 特点:

  • HttpServerCodec = HttpRequestDecoder + HttpResponseEncoder
  • 自动解析 HTTP 请求行、头、体
  • 支持 Chunked 传输

🎯 应用场景:

  • 构建 HTTP 服务器、代理、网关

6.1.2 示例代码

/*** HTTP服务器编解码器示例*/
public class HttpServerCodecExample {/*** 配置HTTP服务器管道*/public static void configureHttpServerPipeline(ChannelPipeline pipeline) {// 添加HTTP编解码器pipeline.addLast("httpCodec", new HttpServerCodec());// 添加HTTP对象聚合器(将HTTP消息聚合为完整的请求/响应对象)pipeline.addLast("httpAggregator", new HttpObjectAggregator(65536));// 添加HTTP请求处理器pipeline.addLast("httpHandler", new SimpleHttpHandler());}/*** 简单HTTP请求处理器*/static class SimpleHttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {// 获取请求信息String uri = request.uri();HttpMethod method = request.method();String content = request.content().toString(StandardCharsets.UTF_8);System.out.println("收到HTTP请求: " + method + " " + uri);System.out.println("请求体: " + content);// 构造响应FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK,Unpooled.copiedBuffer("Hello World!", StandardCharsets.UTF_8));// 设置响应头response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());// 发送响应ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}}
}

6.1.3 流程

HTTP 字节流
HttpRequestDecoder
FullHttpRequest
HttpBusinessHandler
FullHttpResponse
HttpResponseEncoder
HTTP 响应字节流

6.2 HttpClientCodec

6.2.1 概述

特点:

  • HTTP客户端编解码器
  • 用于发送HTTP请求和接收响应
  • 自动处理HTTP协议细节

应用场景:

  • 构建HTTP客户端
  • 发送HTTP请求

6.2.2 示例代码

/*** HTTP客户端编解码器示例*/
public class HttpClientCodecExample {/*** 配置HTTP客户端管道*/public static void configureHttpClientPipeline(ChannelPipeline pipeline) {// 添加HTTP客户端编解码器pipeline.addLast("httpCodec", new HttpClientCodec());// 添加HTTP对象聚合器pipeline.addLast("httpAggregator", new HttpObjectAggregator(65536));// 添加HTTP响应处理器pipeline.addLast("httpHandler", new SimpleHttpResponseHandler());}/*** 发送HTTP请求示例*/public static void sendHttpRequest(ChannelHandlerContext ctx, String url) throws URISyntaxException {URI uri = new URI(url);// 构造HTTP请求FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1,HttpMethod.GET,uri.getRawPath());// 设置请求头request.headers().set(HttpHeaderNames.HOST, uri.getHost());request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);request.headers().set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);// 发送请求ctx.writeAndFlush(request);}/*** 简单HTTP响应处理器*/static class SimpleHttpResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse response) {// 获取响应信息HttpResponseStatus status = response.status();String content = response.content().toString(StandardCharsets.UTF_8);System.out.println("收到HTTP响应: " + status);System.out.println("响应体: " + content);// 关闭连接ctx.close();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}}
}

6.3 HttpObjectAggregator

6.3.1 概述

特点:

  • 将HTTP消息片段聚合为完整的消息
  • 处理分块传输编码
  • 防止内存溢出

应用场景:

  • 处理大型HTTP消息
  • 处理分块传输

6.3.2 示例代码

/*** HTTP对象聚合器示例*/
public class HttpObjectAggregatorExample {/*** 配置支持大文件上传的HTTP服务器*/public static void configureLargeFileServerPipeline(ChannelPipeline pipeline) {// HTTP编解码器pipeline.addLast("httpCodec", new HttpServerCodec());// HTTP对象聚合器(支持10MB的请求)pipeline.addLast("httpAggregator", new HttpObjectAggregator(10 * 1024 * 1024));// 文件上传处理器pipeline.addLast("fileUploadHandler", new FileUploadHandler());}/*** 文件上传处理器*/static class FileUploadHandler extends SimpleChannelInboundHandler<FullHttpRequest> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {try {// 解析multipart请求HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), request);List<InterfaceHttpData> httpDatas = decoder.getBodyHttpDatas();for (InterfaceHttpData data : httpDatas) {if (data.getHttpDataType() == HttpDataType.FileUpload) {DiskFileUpload fileUpload = (DiskFileUpload) data;if (fileUpload.isCompleted()) {System.out.println("文件名: " + fileUpload.getFilename());System.out.println("文件大小: " + fileUpload.length());System.out.println("文件路径: " + fileUpload.getFile());}}}// 发送响应FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK,Unpooled.copiedBuffer("文件上传成功", StandardCharsets.UTF_8));response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);} catch (Exception e) {e.printStackTrace();ctx.close();}}}
}

七、WebSocket 相关 Handler

7.1 WebSocketServerProtocolHandler

7.1.1 概述

✅ 特点:

  • 自动处理 WebSocket 握手升级
  • 处理 Ping/Pong、Close 帧
  • 将 WebSocketFrame 传给业务处理器

🎯 应用场景:

  • 实时聊天、股票行情、在线游戏

7.1.2 示例代码

/*** WebSocket服务器协议处理器示例*/
public class WebSocketServerProtocolHandlerExample {/*** 配置WebSocket服务器管道*/public static void configureWebSocketPipeline(ChannelPipeline pipeline) {// HTTP编解码器pipeline.addLast("httpCodec", new HttpServerCodec());// HTTP对象聚合器pipeline.addLast("httpAggregator", new HttpObjectAggregator(65536));// HTTP请求处理器(处理WebSocket握手请求)pipeline.addLast("httpRequestHandler", new HttpRequestHandler("/ws"));// WebSocket协议处理器pipeline.addLast("webSocketHandler", new WebSocketServerProtocolHandler("/ws",          // WebSocket路径null,           // 子协议(null表示不指定)false,          // 允许扩展65536,          // 最大帧大小false           // 是否发送掩码));// WebSocket消息处理器pipeline.addLast("webSocketFrameHandler", new WebSocketFrameHandler());}/*** HTTP请求处理器(处理WebSocket握手)*/static class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {private final String wsUri;public HttpRequestHandler(String wsUri) {this.wsUri = wsUri;}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {// 如果是WebSocket握手请求,交给WebSocket协议处理器处理if (wsUri.equalsIgnoreCase(request.uri())) {ctx.fireChannelRead(request.retain());return;}// 处理普通HTTP请求handleHttpRequest(ctx, request);}private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) {// 构造简单的HTTP响应FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK,Unpooled.copiedBuffer("WebSocket server is running", StandardCharsets.UTF_8));response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);}}/*** WebSocket帧处理器*/static class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {// 处理文本帧if (frame instanceof TextWebSocketFrame) {TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;String request = textFrame.text();System.out.println("收到WebSocket消息: " + request);// 回复消息ctx.channel().writeAndFlush(new TextWebSocketFrame("Echo: " + request));}// 处理关闭帧else if (frame instanceof CloseWebSocketFrame) {ctx.channel().writeAndFlush(frame.retainedDuplicate()).addListener(ChannelFutureListener.CLOSE);}// 处理ping帧else if (frame instanceof PingWebSocketFrame) {ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content().retain()));}// 处理二进制帧else if (frame instanceof BinaryWebSocketFrame) {ctx.channel().writeAndFlush(new BinaryWebSocketFrame(frame.content().retain()));}}}
}

7.1.3 流程处理

graph LRA[HTTP Upgrade请求] --> B[WebSocketServerProtocolHandler]B --> C[握手成功,升级为WS]C --> D[接收TextWebSocketFrame]D --> E[WebSocketFrameHandler]E --> F[发送TextWebSocketFrame]

7.2 WebSocketClientProtocolHandler

7.2.1 概述

特点:

  • WebSocket客户端协议处理器
  • 自动处理WebSocket握手
  • 支持WebSocket子协议

应用场景:

  • 构建WebSocket客户端
  • 连接WebSocket服务器

7.2.2 示例代码

/*** WebSocket客户端协议处理器示例*/
public class WebSocketClientProtocolHandlerExample {/*** 配置WebSocket客户端管道*/public static void configureWebSocketClientPipeline(ChannelPipeline pipeline, URI webSocketURL) {// HTTP编解码器pipeline.addLast("httpCodec", new HttpClientCodec());// HTTP对象聚合器pipeline.addLast("httpAggregator", new HttpObjectAggregator(8192));// WebSocket客户端协议处理器pipeline.addLast("webSocketHandler", new WebSocketClientProtocolHandler(webSocketURL,           // WebSocket URLWebSocketVersion.V13,   // WebSocket版本null,                   // 子协议false,                  // 是否发送掩码new DefaultHttpHeaders(), // HTTP头1280000                 // 最大帧大小));// WebSocket客户端处理器pipeline.addLast("webSocketClientHandler", new WebSocketClientHandler());}/*** WebSocket客户端处理器*/static class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {@Overridepublic void handlerAdded(ChannelHandlerContext ctx) {System.out.println("WebSocket客户端处理器已添加");}@Overridepublic void channelActive(ChannelHandlerContext ctx) {System.out.println("WebSocket连接已建立");// 发送连接成功的消息ctx.writeAndFlush(new TextWebSocketFrame("Hello WebSocket Server!"));}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, Object msg) {// 处理WebSocket握手完成事件if (msg instanceof FullHttpResponse) {FullHttpResponse response = (FullHttpResponse) msg;System.out.println("WebSocket握手完成: " + response.status());}// 处理WebSocket文本消息else if (msg instanceof TextWebSocketFrame) {TextWebSocketFrame textFrame = (TextWebSocketFrame) msg;System.out.println("收到服务器消息: " + textFrame.text());}// 处理WebSocket二进制消息else if (msg instanceof BinaryWebSocketFrame) {BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) msg;System.out.println("收到二进制消息,长度: " + binaryFrame.content().readableBytes());}}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}}
}

八、Handler选择指南

8.1 根据协议选择

协议类型推荐Handler说明
TCP自定义协议LengthFieldBasedFrameDecoder + LengthFieldPrepender处理粘包拆包
HTTP协议HttpServerCodec/HttpClientCodec完整HTTP支持
WebSocketWebSocketServerProtocolHandlerWebSocket协议支持
文本协议StringEncoder/StringDecoder简单文本处理

8.2 根据功能选择

协议类型推荐Handler说明
安全通信SslHandlerSSL/TLS加密
流量控制FlowControlHandler防止缓冲区溢出
心跳检测IdleStateHandler连接保活
大文件传输WriteBufferWaterMark控制写缓冲区

8.3 性能考虑

  1. 编解码器选择:Protobuf > JSON > XML
  2. 缓冲区管理:合理设置水位标记
  3. 线程模型:避免阻塞IO线程
  4. 内存管理:及时释放ByteBuf资源
http://www.dtcms.com/a/399350.html

相关文章:

  • java服务注册到 Nacos 及相关配置
  • 设计网站与建设wordpress网站部署
  • 扬州鼎盛开发建设有限公司网站简单的ps网页设计教程
  • 本地AI部署成趋势:LocalAl+cpolar安全指南
  • 概率编程实战:使用Pyro/PyMC3构建贝叶斯模型
  • 数据结构系列之链表
  • 194-基于Python的脑肿瘤患者数据分析可视化
  • 在 Mac 上无线挂载 Android /sdcard
  • Nature论文解读DeepSeek R1:MoE架构如何重构高效推理的技术范式
  • 拆炸弹-定长滑动窗口/环形数组
  • 成都市城乡建设局网站重庆市建设施工安全网站
  • 力扣1003
  • LeetCode 386 字典序排数 Swift 题解:模拟字典翻页的遍历技巧
  • 如何给 wot-ui(wot-design-uni)日历里给某几天加「原点」标注 —— 实战指南
  • 网站分析培训班西安有哪些大公司
  • Vue——02 Vue指令和Vue对象的配置项
  • 商城网站模板框架购物网站如何做推广
  • html个人网站设计网络营销推广的方式都有哪些
  • 【Linux】进程概念(五) 命令行参数与环境变量的深度解析
  • 网站认领微平台公众号
  • 微盟网站模板某购物网站开发项目
  • ManualResetEvent:C# 线程同步工具
  • 手机移动端网站怎么做的第一ppt模板官网
  • C# 车牌识别系统实现
  • 国内做医疗耗材的网站宁波seo推广哪家公司好
  • vue3中返回带参数如何实现?
  • Kafka Rebalance机制全解析
  • 温州集团网站建设网站怎么做外部链接
  • 华为云产品体系选择
  • 公司网站站群是什么赣州网上商城入驻方案