ChannelInboundHandlerAdapter 和 SimpleChannelInboundHandler 都是 Netty 提供的处理器基类。
它们之间的主要区别:
- ChannelInboundHandlerAdapter
ChannelInboundHandlerAdapter 是一个通用的处理器基类,继承自 ChannelInboundHandler,用于处理 入站消息(即从客户端到服务端的消息)。
它不做任何具体的消息类型限制,因此适用于处理各种类型的入站消息。
你可以重写 channelRead 方法来处理不同类型的消息,或者重写 exceptionCaught 等方法处理异常。
特点:
通用:没有指定消息类型,你可以在 channelRead 方法中处理任何类型的入站消息。
灵活:你需要手动判断消息的类型,进行相应的处理。
适用场景:适用于处理多种不同类型的消息,或者当你希望处理多个类型的消息时。
public class WebSocketServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof TextWebSocketFrame) {
// 处理 TextWebSocketFrame 消息
String request = ((TextWebSocketFrame) msg).text();
ctx.channel().writeAndFlush(new TextWebSocketFrame("Hello, " + request));
} else {
super.channelRead(ctx, msg); // 转发其他消息
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
- SimpleChannelInboundHandler
SimpleChannelInboundHandler 是 ChannelInboundHandlerAdapter 的一个子类,它专门用于处理某一特定类型的入站消息。你需要在创建 SimpleChannelInboundHandler 时指定消息类型 T(如 TextWebSocketFrame、ByteBuf 等)。
它在处理完每个消息后会自动释放该消息,因此避免了手动管理消息的生命周期(比如调用 ReferenceCountUtil.release)。
如果消息类型不匹配,它会抛出异常,这使得它更适合处理单一类型的消息,简化了类型检查。
特点:
泛型:SimpleChannelInboundHandler 强制指定一个消息类型,这样可以避免手动类型检查,减少代码出错的可能性。
自动释放消息:在处理完消息后,SimpleChannelInboundHandler 会自动释放消息,因此你不需要关心资源的回收。
简洁:适合处理特定类型的消息,代码更简洁、可读性更好。
public class WebSocketServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
// 直接处理 TextWebSocketFrame 消息,不需要类型检查
String request = msg.text();
ctx.channel().writeAndFlush(new TextWebSocketFrame("Hello, " + request));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
WebSocket 帧类型
- Text WebSocket Frame (文本帧)
用于传输文本数据,通常是 UTF-8 编码的字符串。
这类帧对应于 TextWebSocketFrame 类。
TextWebSocketFrame 是一个 单一类型的消息框架,在 Netty 中用于表示 WebSocket 连接中传输的文本消息。 - Binary WebSocket Frame (二进制帧)
用于传输二进制数据(如文件、图片、视频等)。
对应于 BinaryWebSocketFrame 类。
这种类型的 WebSocket 帧通常是用于传输二进制数据。 - Close WebSocket Frame (关闭帧)
用于关闭 WebSocket 连接的帧。
对应于 CloseWebSocketFrame 类。
发送此类型的帧可以通知对方关闭连接。 - Ping WebSocket Frame (Ping 帧)
用于测试 WebSocket 连接是否正常可用(心跳)。
对应于 PingWebSocketFrame 类。
一般由客户端或服务器发送,收到 Ping 后,另一方通常会发送一个 Pong 帧作为响应。 - Pong WebSocket Frame (Pong 帧)
用于回应 Ping 帧。
对应于 PongWebSocketFrame 类。
TextWebSocketFrame 的作用
TextWebSocketFrame 是专门用于处理 文本消息 的 WebSocket 帧,它继承了 WebSocketFrame,并封装了文本内容。在实际的 WebSocket 应用中,客户端和服务器通常会通过发送和接收 TextWebSocketFrame 来交换信息,通常这些信息都是 UTF-8 编码的文本。