WebSocketFrame
WebSocketFrame 是 Netty 中用于表示 WebSocket 消息帧的抽象基类,封装了帧的内容、分片标志和扩展位信息,供各类具体帧(如文本、二进制、控制帧)继承使用。
public abstract class WebSocketFrame extends BufferHolder<WebSocketFrame> {// 表示是否是当前 WebSocket 消息的最后一个分片(frame)。private final boolean finalFragment;// 表示 RSV1/RSV2/RSV3 位(协议保留字段),通常用于 WebSocket 扩展(如压缩、加密扩展等)。private final int rsv;protected WebSocketFrame(Buffer binaryData) {this(true, 0, binaryData);}protected WebSocketFrame(Send<Buffer> binaryData) {super(binaryData);finalFragment = true;rsv = 0;}protected WebSocketFrame(boolean finalFragment, int rsv, Buffer binaryData) {super(binaryData);this.finalFragment = finalFragment;this.rsv = rsv;}protected WebSocketFrame(WebSocketFrame copyFrom, Buffer binaryData) {super(binaryData);finalFragment = copyFrom.finalFragment;rsv = copyFrom.rsv;}// 标识当前帧是否是消息的最后一部分(WebSocket 支持帧分片)public boolean isFinalFragment() {return finalFragment;}// 返回 RSV(Reserved Bits),可用于判断是否启用 WebSocket 扩展,如压缩 (permessage-deflate)public int rsv() {return rsv;}public Buffer binaryData() {return getBuffer();}@Overridepublic String toString() {return StringUtil.simpleClassName(this) + "(data: " + getBuffer().toString(defaultCharset()) + ')';}
}
PingWebSocketFrame
PingWebSocketFrame
是 Netty 中表示 WebSocket Ping 控制帧的类,用于发送心跳检测数据,继承自 WebSocketFrame
并实现帧复制逻辑。
public class PingWebSocketFrame extends WebSocketFrame {public PingWebSocketFrame(Buffer binaryData) {super(binaryData);}public PingWebSocketFrame(boolean finalFragment, int rsv, Buffer binaryData) {super(finalFragment, rsv, binaryData);}private PingWebSocketFrame(PingWebSocketFrame copyFrom, Buffer data) {super(copyFrom, data);}@Overrideprotected WebSocketFrame receive(Buffer buf) {return new PingWebSocketFrame(this, buf);}
}
PongWebSocketFrame
PongWebSocketFrame
是 Netty 中用于响应 Ping
控制帧的 WebSocket Pong
帧实现,继承自 WebSocketFrame
,支持数据内容和帧复制功能。
public class PongWebSocketFrame extends WebSocketFrame {public PongWebSocketFrame(Buffer binaryData) {super(binaryData);}public PongWebSocketFrame(Send<Buffer> binaryData) {super(binaryData);}public PongWebSocketFrame(boolean finalFragment, int rsv, Buffer binaryData) {super(finalFragment, rsv, binaryData);}private PongWebSocketFrame(PongWebSocketFrame copyFrom, Buffer data) {super(copyFrom, data);}@Overrideprotected WebSocketFrame receive(Buffer buf) {return new PongWebSocketFrame(this, buf);}
}
BinaryWebSocketFrame
BinaryWebSocketFrame
是 Netty 中用于传输二进制数据的 WebSocket 数据帧,支持设置是否为最后一帧以及协议扩展位。
public class BinaryWebSocketFrame extends WebSocketFrame {public BinaryWebSocketFrame(Buffer binaryData) {super(binaryData);}public BinaryWebSocketFrame(boolean finalFragment, int rsv, Buffer binaryData) {super(finalFragment, rsv, binaryData);}private BinaryWebSocketFrame(BinaryWebSocketFrame copyFrom, Buffer data) {super(copyFrom, data);}@Overrideprotected WebSocketFrame receive(Buffer buf) {return new BinaryWebSocketFrame(this, buf);}
}
TextWebSocketFrame
TextWebSocketFrame
是 Netty 中用于传输 UTF-8 编码文本的 WebSocket 数据帧,支持字符串构造、扩展位设置以及是否为最后一帧的标识。
public class TextWebSocketFrame extends WebSocketFrame {public TextWebSocketFrame(BufferAllocator allocator, String text) {super(fromText(allocator, text));}public TextWebSocketFrame(Buffer binaryData) {super(binaryData);}public TextWebSocketFrame(BufferAllocator allocator, boolean finalFragment, int rsv, String text) {super(finalFragment, rsv, fromText(allocator, text));}private TextWebSocketFrame(TextWebSocketFrame copyFrom, Buffer data) {super(copyFrom, data);}private static Buffer fromText(BufferAllocator allocator, String text) {if (text == null || text.isEmpty()) {return allocator.allocate(0);} else {return allocator.copyOf(text, UTF_8);}}public TextWebSocketFrame(boolean finalFragment, int rsv, Buffer binaryData) {super(finalFragment, rsv, binaryData);}/*** Returns the text data in this frame.*/public String text() {return binaryData().toString(UTF_8);}@Overrideprotected WebSocketFrame receive(Buffer buf) {return new TextWebSocketFrame(this, buf);}
}
ContinuationWebSocketFrame
ContinuationWebSocketFrame
是用于 WebSocket 消息分片场景的续帧类型,可承载文本或二进制数据,支持设置是否为最终帧和协议扩展位。
public class ContinuationWebSocketFrame extends WebSocketFrame {public ContinuationWebSocketFrame(Buffer binaryData) {super(binaryData);}public ContinuationWebSocketFrame(boolean finalFragment, int rsv, Buffer binaryData) {super(finalFragment, rsv, binaryData);}public ContinuationWebSocketFrame(BufferAllocator allocator, boolean finalFragment, int rsv, String text) {this(finalFragment, rsv, fromText(allocator, text));}private ContinuationWebSocketFrame(ContinuationWebSocketFrame copyFrom, Buffer data) {super(copyFrom, data);}public String text() {return binaryData().toString(StandardCharsets.UTF_8);}private static Buffer fromText(BufferAllocator allocator, String text) {if (text == null || text.isEmpty()) {return allocator.allocate(0);} else {return allocator.copyOf(text.getBytes(StandardCharsets.UTF_8));}}@Overrideprotected WebSocketFrame receive(Buffer buf) {return new ContinuationWebSocketFrame(this, buf);}
}
CloseWebSocketFrame
CloseWebSocketFrame
表示 WebSocket 连接关闭帧,包含关闭状态码和可选的关闭原因,用于优雅地关闭连接。
public class CloseWebSocketFrame extends WebSocketFrame {public CloseWebSocketFrame(BufferAllocator allocator, WebSocketCloseStatus status) {this(allocator, requireValidStatusCode(status.code()), status.reasonText());}public CloseWebSocketFrame(BufferAllocator allocator, WebSocketCloseStatus status, String reasonText) {this(allocator, requireValidStatusCode(status.code()), reasonText);}public CloseWebSocketFrame(BufferAllocator allocator, int statusCode, String reasonText) {this(allocator, true, 0, requireValidStatusCode(statusCode), reasonText);}public CloseWebSocketFrame(BufferAllocator allocator, boolean finalFragment, int rsv) {this(finalFragment, rsv, allocator.allocate(0));}public CloseWebSocketFrame(BufferAllocator allocator, boolean finalFragment, int rsv, int statusCode, String reasonText) {super(finalFragment, rsv, newBinaryData(allocator, requireValidStatusCode(statusCode), reasonText));}public CloseWebSocketFrame(boolean finalFragment, int rsv, Buffer binaryData) {super(finalFragment, rsv, binaryData);}private CloseWebSocketFrame(CloseWebSocketFrame copyFrom, Buffer data) {super(copyFrom, data);}// 构造符合 WebSocket Close 帧格式的二进制数据,包含状态码和 UTF-8 编码的关闭原因文本。private static Buffer newBinaryData(BufferAllocator allocator, short statusCode, String reasonText) {if (reasonText == null) {reasonText = StringUtil.EMPTY_STRING;}final Buffer binaryData;if (!reasonText.isEmpty()) {byte[] reasonTextBytes = reasonText.getBytes(StandardCharsets.UTF_8);binaryData = allocator.allocate(2 + reasonTextBytes.length);binaryData.writeShort(statusCode);binaryData.writeBytes(reasonTextBytes);} else {binaryData = allocator.allocate(2).writeShort(statusCode);}return binaryData;}public int statusCode() {Buffer binaryData = binaryData();if (binaryData == null || binaryData.readableBytes() < 2) {return -1;}return binaryData.getUnsignedShort(binaryData.readerOffset());}public String reasonText() {Buffer binaryData = binaryData();if (binaryData == null || binaryData.readableBytes() <= 2) {return "";}int base = binaryData.readerOffset();try {binaryData.skipReadableBytes(2);return binaryData.toString(StandardCharsets.UTF_8);} finally {binaryData.readerOffset(base);}}@Overrideprotected WebSocketFrame receive(Buffer buf) {return new CloseWebSocketFrame(this, buf);}static short requireValidStatusCode(int statusCode) {if (WebSocketCloseStatus.isValidStatusCode(statusCode)) {return (short) statusCode;} else {throw new IllegalArgumentException("WebSocket close status code does NOT comply with RFC-6455: " + statusCode);}}
}