cWebSocketFrame Class Reference
📋 Class Overview
cWebSocketFrame is a WebSocket frame parsing and building class, used to handle WebSocket protocol frame formats.
Design Features
- Read-only parsing -
ParseHeader()does not modify input data - Separated unmasking - After parsing header, extract and unmask payload separately
- Build support - Can build various types of WebSocket frames
- Fragmentation support - Correctly handles fragmented frames (CONTINUATION)
📊 Property Reference
FIN - Final Frame Flag
Type: Boolean
Read/Write: Read-only (after parsing)
Description: Indicates whether this is the last frame of the message.
If oFrame.FIN Then
Debug.Print "This is the last frame"
Else
Debug.Print "More frames to come"
End IfRSV1, RSV2, RSV3 - Reserved Bits
Type: Boolean
Read/Write: Read-only (after parsing)
Description: Reserved bits in the WebSocket protocol. Usually False, used for extensions.
If oFrame.RSV1 Or oFrame.RSV2 Or oFrame.RSV3 Then
Debug.Print "Extension used"
End IfOpCode - Operation Code
Type: WsOpCode (Enum)
Read/Write: Read-only (after parsing)
Values:
| OpCode | Constant | Description |
|---|---|---|
| 0 | WS_OPCODE_CONTINUATION | Continuation frames for fragmented messages |
| 1 | WS_OPCODE_TEXT | Text data frame |
| 2 | WS_OPCODE_BINARY | Binary data frame |
| 8 | WS_OPCODE_CLOSE | Connection close frame |
| 9 | WS_OPCODE_PING | Ping frame |
| 10 | WS_OPCODE_PONG | Pong frame |
Select Case oFrame.OpCode
Case WS_OPCODE_TEXT
Debug.Print "Text frame"
Case WS_OPCODE_BINARY
Debug.Print "Binary frame"
Case WS_OPCODE_CLOSE
Debug.Print "Close frame"
Case WS_OPCODE_PING
Debug.Print "Ping frame"
Case WS_OPCODE_PONG
Debug.Print "Pong frame"
End SelectHasMask - Has Masking
Type: Boolean
Read/Write: Read-only (after parsing)
Description: Indicates whether the payload is masked. Frames sent by client must be masked, frames sent by server should not be masked.
If oFrame.HasMask Then
Debug.Print "Frame is masked"
Else
Debug.Print "Frame is not masked"
End IfPayloadLength - Payload Length
Type: Long
Read/Write: Read-only (after parsing)
Description: The length of the frame payload data in bytes.
Debug.Print "Payload length: " & oFrame.PayloadLength & " bytes"HeaderLength - Header Length
Type: Long
Read/Write: Read-only (after parsing)
Description: The length of the WebSocket frame header (including extended length and masking key).
Debug.Print "Header length: " & oFrame.HeaderLength & " bytes"TotalFrameLength - Total Frame Length
Type: Long
Read/Write: Read-only (after parsing)
Description: The complete frame length (header + payload).
Debug.Print "Total frame length: " & oFrame.TotalFrameLength & " bytes"IsValid - Is Valid
Type: Boolean
Read/Write: Read-only (after parsing)
Description: Whether the frame header was successfully parsed and is valid.
If oFrame.IsValid Then
Debug.Print "Frame is valid"
Else
Debug.Print "Frame is invalid: " & oFrame.ErrorMessage
End IfErrorMessage - Error Message
Type: String
Read/Write: Read-only (after parsing)
Description: Contains error description when frame is invalid.
If Not oFrame.IsValid Then
Debug.Print "Error: " & oFrame.ErrorMessage
End IfIsControlFrame - Is Control Frame
Type: Boolean
Read/Write: Read-only
Description: Determines whether the current frame is a control frame (CLOSE, PING, PONG).
If oFrame.IsControlFrame Then
Debug.Print "This is a control frame"
' Control frames cannot be fragmented
If Not oFrame.FIN Then
Debug.Print "Warning: Control frames should not be fragmented"
End If
End IfIsDataFrame - Is Data Frame
Type: Boolean
Read/Write: Read-only
Description: Determines whether the current frame is a data frame (TEXT, BINARY, CONTINUATION).
If oFrame.IsDataFrame Then
Debug.Print "This is a data frame"
' Can be fragmented
End If🚀 Method Reference
ParseHeader - Parse Frame Header
Syntax:
Public Function ParseHeader(ByRef Buffer As cByteBuffer) As BooleanParameters:
| Parameter | Type | Description |
|---|---|---|
Buffer | cByteBuffer | Byte buffer |
Return Value: Boolean - Returns True if parsing successful, otherwise False
Description:
- Read-only operation - Does not modify or consume buffer data
- Requires at least 2 bytes of data to parse
- After parsing, frame header information can be accessed through properties
Example:
Dim oFrame As New cWebSocketFrame
Dim oBuffer As cByteBuffer
Set oBuffer = New cByteBuffer
oBuffer.Append baReceivedData
' Parse header
If oFrame.ParseHeader(oBuffer) Then
Debug.Print "Frame type: " & oFrame.OpCode
Debug.Print "Payload length: " & oFrame.PayloadLength
' Check if complete
If oFrame.IsCompleteFrame(oBuffer) Then
' Extract payload
Dim baPayload() As Byte
baPayload = oFrame.ExtractPayload(oBuffer)
End If
Else
Debug.Print "Parsing failed: " & oFrame.ErrorMessage
End IfIsCompleteFrame - Check if Frame is Complete
Syntax:
Public Function IsCompleteFrame(ByRef Buffer As cByteBuffer) As BooleanParameters:
| Parameter | Type | Description |
|---|---|---|
Buffer | cByteBuffer | Byte buffer |
Return Value: Boolean - Returns True if frame is complete, otherwise False
Description:
- Must call
ParseHeader()successfully first - Checks if buffer contains a complete frame
Example:
If oFrame.ParseHeader(oBuffer) Then
' Check completeness
If oFrame.IsCompleteFrame(oBuffer) Then
' Can extract
baPayload = oFrame.ExtractPayload(oBuffer)
Else
Debug.Print "Need more data"
End If
End IfExtractPayload - Extract and Unmask Payload
Syntax:
Public Function ExtractPayload(ByRef Buffer As cByteBuffer) As Byte()Parameters:
| Parameter | Type | Description |
|---|---|---|
Buffer | cByteBuffer | Byte buffer |
Return Value: Byte() - Extracted payload data (unmasked)
Description:
- Must call
ParseHeader()successfully first - Will consume the entire frame (remove from buffer)
- Automatically performs unmasking (if frame has masking)
Example:
' Complete frame processing flow
If oFrame.ParseHeader(oBuffer) Then
If oFrame.IsCompleteFrame(oBuffer) Then
' Extract payload (consume frame)
Dim baPayload() As Byte
baPayload = oFrame.ExtractPayload(oBuffer)
' Process payload
ProcessPayload baPayload, oFrame.OpCode
End If
End IfSkipFrame - Skip Frame
Syntax:
Public Sub SkipFrame(ByRef Buffer As cByteBuffer)Parameters:
| Parameter | Type | Description |
|---|---|---|
Buffer | cByteBuffer | Byte buffer |
Description: Removes the entire frame from the buffer without extracting payload. Used for processing unwanted frames.
Example:
' Skip control frames
If oFrame.ParseHeader(oBuffer) Then
If oFrame.IsControlFrame Then
' Skip control frame
oFrame.SkipFrame oBuffer
Else
' Process data frame
baPayload = oFrame.ExtractPayload(oBuffer)
End If
End IfBuildFrame - Build Frame
Syntax:
Public Function BuildFrame(ByRef Payload() As Byte, _
ByVal OpCode As WsOpCode, _
Optional ByVal UseMask As Boolean = False, _
Optional ByVal IsFinal As Boolean = True) As Byte()Parameters:
| Parameter | Type | Description |
|---|---|---|
Payload | Byte() | Payload data |
OpCode | WsOpCode | Operation code |
UseMask | Boolean | Whether to mask |
IsFinal | Boolean | Whether this is the final frame |
Return Value: Byte() - Complete WebSocket frame byte array
Description:
- Client sending must be masked (
UseMask = True) - Server sending should not be masked (
UseMask = False) - Automatically generates random masking key when masking
Example:
' Client sending (must mask)
Dim baFrame() As Byte
Dim baData() As Byte
baData = StringToUTF8("Hello")
baFrame = oFrame.BuildFrame(baData, WS_OPCODE_TEXT, True, True)
Socket.SendData baFrame
' Server sending (no mask)
baFrame = oFrame.BuildFrame(baData, WS_OPCODE_TEXT, False, True)
Socket.SendData baFrameBuildTextFrame - Build Text Frame
Syntax:
Public Function BuildTextFrame(ByVal Text As String, _
Optional ByVal UseMask As Boolean = False) As Byte()Parameters:
| Parameter | Type | Description |
|---|---|---|
Text | String | Text content |
UseMask | Boolean | Whether to mask |
Return Value: Byte() - WebSocket text frame
Description: Text is automatically converted to UTF-8 encoding.
Example:
' Client sending text
Dim baFrame() As Byte
baFrame = oFrame.BuildTextFrame("Hello WebSocket!", True)
Socket.SendData baFrameBuildBinaryFrame - Build Binary Frame
Syntax:
Public Function BuildBinaryFrame(ByRef Data() As Byte, _
Optional ByVal UseMask As Boolean = False) As Byte()Parameters:
| Parameter | Type | Description |
|---|---|---|
Data() | Byte() | Binary data |
UseMask | Boolean | Whether to mask |
Return Value: Byte() - WebSocket binary frame
Example:
' Client sending binary
Dim baData() As Byte
baData = LoadFile("image.png")
Dim baFrame() As Byte
baFrame = oFrame.BuildBinaryFrame(baData, True)
Socket.SendData baFrameBuildCloseFrame - Build Close Frame
Syntax:
Public Function BuildCloseFrame(Optional ByVal StatusCode As WsCloseCode = WS_CLOSE_NORMAL, _
Optional ByVal Reason As String = "", _
Optional ByVal UseMask As Boolean = False) As Byte()Parameters:
| Parameter | Type | Description |
|---|---|---|
StatusCode | WsCloseCode (Optional) | Close status code |
Reason | String (Optional) | Close reason |
UseMask | Boolean (Optional) | Whether to mask |
Return Value: Byte() - WebSocket close frame
Example:
' Normal close
Dim baFrame() As Byte
baFrame = oFrame.BuildCloseFrame(WS_CLOSE_NORMAL, "Normal closure", True)
Socket.SendData baFrame
' Protocol error
baFrame = oFrame.BuildCloseFrame(WS_CLOSE_PROTOCOL_ERROR, "Invalid frame", True)
Socket.SendData baFrameBuildPingFrame - Build Ping Frame
Syntax:
Public Function BuildPingFrame(ByRef Payload() As Byte, _
Optional ByVal UseMask As Boolean = False) As Byte()Parameters:
| Parameter | Type | Description |
|---|---|---|
Payload() | Byte() | Ping payload |
UseMask | Boolean (Optional) | Whether to mask |
Return Value: Byte() - WebSocket Ping frame
Example:
' Send empty Ping
Dim baEmpty() As Byte
Dim baFrame() As Byte
baFrame = oFrame.BuildPingFrame(baEmpty, True)
Socket.SendData baFrame
' Send Ping with data
Dim baData() As Byte
baData = StringToUTF8("ping")
baFrame = oFrame.BuildPingFrame(baData, True)
Socket.SendData baFrameBuildPongFrame - Build Pong Frame
Syntax:
Public Function BuildPongFrame(ByRef Payload() As Byte, _
Optional ByVal UseMask As Boolean = False) As Byte()Parameters:
| Parameter | Type | Description |
|---|---|---|
Payload() | Byte() | Pong payload |
UseMask | Boolean (Optional) | Whether to mask |
Return Value: Byte() - WebSocket Pong frame
Example:
' Reply Pong (using Ping's payload)
Dim baFrame() As Byte
baFrame = oFrame.BuildPongFrame(baPingPayload, True)
Socket.SendData baFrame📝 Usage Examples
Basic Frame Parsing Flow
Private Sub ProcessWebSocketFrame(oBuffer As cByteBuffer)
Dim oFrame As New cWebSocketFrame
Do While oBuffer.Size >= 2
' 1. Parse header (read-only)
If Not oFrame.ParseHeader(oBuffer) Then
Debug.Print "Need more data"
Exit Do
End If
' 2. Check completeness
If Not oFrame.IsCompleteFrame(oBuffer) Then
Debug.Print "Need more data"
Exit Do
End If
' 3. Extract payload (consume frame)
Dim baPayload() As Byte
baPayload = oFrame.ExtractPayload(oBuffer)
' 4. Process frame
Select Case oFrame.OpCode
Case WS_OPCODE_TEXT
Dim sText As String
sText = UTF8ToString(baPayload)
Debug.Print "Text: " & sText
Case WS_OPCODE_BINARY
Debug.Print "Binary: " & (UBound(baPayload) + 1) & " bytes"
Case WS_OPCODE_CLOSE
Debug.Print "Close frame"
ProcessCloseFrame baPayload
Case WS_OPCODE_PING
Debug.Print "Ping frame"
' Auto reply Pong
Dim baPong() As Byte
baPong = oFrame.BuildPongFrame(baPayload, False)
SendData baPong
Case WS_OPCODE_PONG
Debug.Print "Pong frame"
End Select
Loop
End SubBuild and Send Frame
' Client sending text
Private Sub SendTextMessage(ByVal sText As String)
Dim oFrame As New cWebSocketFrame
Dim baFrame() As Byte
' Build text frame (must mask)
baFrame = oFrame.BuildTextFrame(sText, True)
' Send
m_Socket.SendData baFrame
End Sub
' Client sending binary
Private Sub SendBinaryMessage(ByVal baData() As Byte)
Dim oFrame As New cWebSocketFrame
Dim baFrame() As Byte
' Build binary frame (must mask)
baFrame = oFrame.BuildBinaryFrame(baData, True)
' Send
m_Socket.SendData baFrame
End Sub
' Send close frame
Private Sub SendCloseFrame()
Dim oFrame As New cWebSocketFrame
Dim baFrame() As Byte
' Build close frame (must mask)
baFrame = oFrame.BuildCloseFrame(WS_CLOSE_NORMAL, "Normal closure", True)
' Send
m_Socket.SendData baFrame
End SubLast Updated: 2026-01-10