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);}}
}