Skip to content

WebSocket Development Guide

Table of Contents


Overview

WebSocket is a protocol for full-duplex communication over a single TCP connection. The new WebSocket library provides separated client and server implementations, supporting text and binary message transmission, with efficient buffer management and comprehensive error handling.

Key Features

  • Separated Architecture - Independent implementations of client (cWebSocketClient) and server (cWebSocketServer)
  • Protocol Support - Complete WebSocket protocol implementation (RFC 6455)
  • Message Types - Supports both text and binary messages
  • Frame Parser - cWebSocketFrame class dedicated to frame parsing and building
  • Efficient Buffering - cByteBuffer class provides pre-allocation and auto-growth strategies
  • Event-driven - Handles all network events through event mechanism
  • Broadcasting - Server supports broadcasting messages to all clients

Project Structure

Websocket/
念岸岸 Client/
岫   念岸岸 frmClient.frm      # Client form
岫   念岸岸 WsClient.vbp       # Client project
岫   弩岸岸 WsClient.vbw
念岸岸 Server/
岫   念岸岸 frmServer.frm      # Server form
岫   念岸岸 WsServer.vbp       # Server project
岫   弩岸岸 WsServer.vbw
弩岸岸 README.md              # Example description

Library Architecture

newWebsocket/
念岸岸 mWebSocketUtils.bas           # Common utility module (UTF-8, Base64, SHA1, enum definitions)
念岸岸 cByteBuffer.cls               # High-performance byte buffer: pre-allocation, auto-growth, minimal memory operations
念岸岸 cWebSocketFrame.cls           # WebSocket frame parser: read-only parsing, separated unmask operations
念岸岸 cWebSocketClient.cls          # WebSocket client
念岸岸 cWebSocketServer.cls          # WebSocket server
弩岸岸 cWebSocketServerClient.cls    # Server client connection information

Quick Start

Requirements

  • Visual Basic 6.0 or higher
  • VBMAN.dll library (located in ..\..\..\vbman\dist\DLL\)

Reference Library

  1. Open project WsClient.vbp or WsServer.vbp
  2. Ensure VBMANLIB library is referenced
  3. Check reference path: ..\..\..\vbman\dist\DLL\VBMAN.dll

Running the Example

  1. Start Server

    • Open Server/WsServer.vbp
    • Run the project
    • Click "Start Service" button
    • Default listening port is 8080
  2. Start Client

    • Open Client/WsClient.vbp
    • Run the project
    • Enter server address ws://127.0.0.1:8080
    • Click "Connect" button
    • Send messages after successful connection
  3. Test Communication

    • Enter a message in the client and click "Send"
    • Server will echo the message
    • Sending "broadcast" will trigger server broadcast functionality

WebSocket Client

client.png

Creating a Client

vb
Private WithEvents m_WsClient As cWebSocketClient

Private Sub InitializeClient()
    If m_WsClient Is Nothing Then
        Set m_WsClient = New cWebSocketClient
    End If
End Sub

Connecting to Server

vb
Private Sub ConnectToServer(ByVal sURL As String)
    On Error GoTo EH
    
    InitializeClient()
    m_WsClient.Connect sURL
    
    LogMessage "Connecting to: " & sURL
    Exit Sub

EH:
    LogMessage "Connection failed: " & Err.Description
End Sub

Parameters:

  • sURL: WebSocket server URL
    • Format: ws://host:port or wss://host:port (encrypted)
    • Example: ws://127.0.0.1:8080

Sending Text Message

vb
Private Sub SendTextMessage(sMessage As String)
    On Error GoTo EH
    
    If Not m_WsClient Is Nothing And m_WsClient.State = WS_STATE_OPEN Then
        m_WsClient.SendText sMessage
        LogMessage "Sent: " & sMessage
    End If
    Exit Sub

EH:
    LogMessage "Send failed: " & Err.Description
End Sub

Sending Binary Message

vb
Private Sub SendBinaryMessage(Data() As Byte)
    On Error GoTo EH
    
    If Not m_WsClient Is Nothing And m_WsClient.State = WS_STATE_OPEN Then
        m_WsClient.SendBinary Data
        LogMessage "Sent binary data: " & (UBound(Data) + 1) & " bytes"
    End If
    Exit Sub

EH:
    LogMessage "Send failed: " & Err.Description
End Sub

Sending Ping Frame

vb
Private Sub SendPing(Optional Data() As Byte)
    On Error GoTo EH
    
    If Not m_WsClient Is Nothing And m_WsClient.State = WS_STATE_OPEN Then
        m_WsClient.Ping Data
        LogMessage "Ping sent"
    End If
    Exit Sub

EH:
    LogMessage "Ping send failed: " & Err.Description
End Sub

Disconnecting

vb
Private Sub Disconnect(Optional ByVal Code As WsCloseCode = WS_CLOSE_NORMAL, Optional ByVal Reason As String = "")
    If Not m_WsClient Is Nothing Then
        m_WsClient.CloseConnection Code, Reason
        LogMessage "Disconnected"
    End If
End Sub

Close Code Description:

  • WS_CLOSE_NORMAL (1000): Normal closure
  • WS_CLOSE_GOING_AWAY (1001): Endpoint going away
  • WS_CLOSE_PROTOCOL_ERROR (1002): Protocol error
  • WS_CLOSE_UNSUPPORTED (1003): Unsupported data type
  • WS_CLOSE_NO_STATUS (1005): No status code
  • WS_CLOSE_ABNORMAL (1006): Abnormal closure
  • WS_CLOSE_INVALID_PAYLOAD (1007): Invalid data
  • WS_CLOSE_POLICY_VIOLATION (1008): Policy violation
  • WS_CLOSE_MESSAGE_TOO_BIG (1009): Message too large
  • WS_CLOSE_MANDATORY_EXT (1010): Mandatory extension missing
  • WS_CLOSE_INTERNAL_ERROR (1011): Internal error
  • WS_CLOSE_TLS_HANDSHAKE (1015): TLS handshake failed

Complete Example

Refer to Client/frmClient.frm file:

vb
Private Sub cmdConnect_Click()
    On Error GoTo EH
    
    If m_WsClient Is Nothing Then
        Set m_WsClient = New cWebSocketClient
    End If
    
    m_WsClient.Connect txtURL.Text
    
    LogMessage "Connecting to: " & txtURL.Text
    cmdConnect.Enabled = False
    Exit Sub
EH:
    LogMessage "Connection failed: " & Err.Description
End Sub

Private Sub cmdSend_Click()
    On Error GoTo EH

    If Not m_WsClient Is Nothing And m_WsClient.State = WS_STATE_OPEN Then
        m_WsClient.SendText txtMessage.Text
        LogMessage "Sent: " & txtMessage.Text
    End If
    Exit Sub
EH:
    LogMessage "Send failed: " & Err.Description
End Sub

Private Sub UpdateUI(bConnected As Boolean)
    cmdConnect.Enabled = Not bConnected
    cmdDisconnect.Enabled = bConnected
    cmdSend.Enabled = bConnected
End Sub

WebSocket Server

server

Creating a Server

vb
Private WithEvents m_WsServer As cWebSocketServer

Private Sub InitializeServer()
    If m_WsServer Is Nothing Then
        Set m_WsServer = New cWebSocketServer
    End If
End Sub

Starting to Listen

vb
Private Sub StartServer(ByVal lPort As Long)
    On Error GoTo EH
    
    InitializeServer()
    m_WsServer.Listen lPort
    
    LogMessage "WebSocket server started, listening on port: " & lPort
    Exit Sub

EH:
    LogMessage "Service start failed: " & Err.Description
End Sub

Stopping Service

vb
Private Sub StopServer()
    If Not m_WsServer Is Nothing Then
        m_WsServer.StopServer
        LogMessage "WebSocket server stopped"
    End If
End Sub

Sending Message to Specific Client

vb
Private Sub SendToClient(ByVal ClientID As String, sMessage As String)
    On Error GoTo EH
    
    m_WsServer.SendText ClientID, sMessage
    LogMessage "Sent message to client " & ClientID & ": " & sMessage
    Exit Sub

EH:
    LogMessage "Send failed: " & Err.Description
End Sub

Sending Binary Message to Specific Client

vb
Private Sub SendBinaryToClient(ByVal ClientID As String, Data() As Byte)
    On Error GoTo EH
    
    m_WsServer.SendBinary ClientID, Data
    LogMessage "Sent binary data to client " & ClientID & ": " & (UBound(Data) + 1) & " bytes"
    Exit Sub

EH:
    LogMessage "Send failed: " & Err.Description
End Sub

Broadcasting Message

vb
Private Sub BroadcastMessage(sMessage As String, Optional ByVal ExcludeClientID As String = "")
    On Error GoTo EH
    
    m_WsServer.BroadcastText sMessage, ExcludeClientID
    LogMessage "Broadcast message: " & sMessage
    Exit Sub

EH:
    LogMessage "Broadcast failed: " & Err.Description
End Sub

Parameters:

  • sMessage: Message to broadcast
  • ExcludeClientID: Optional, client ID to exclude from broadcast (won't receive broadcast)

Broadcasting Binary Message

vb
Private Sub BroadcastBinaryMessage(Data() As Byte, Optional ByVal ExcludeClientID As String = "")
    On Error GoTo EH
    
    m_WsServer.BroadcastBinary Data, ExcludeClientID
    LogMessage "Broadcast binary data: " & (UBound(Data) + 1) & " bytes"
    Exit Sub

EH:
    LogMessage "Broadcast failed: " & Err.Description
End Sub

Disconnecting Specific Client

vb
Private Sub DisconnectClient(ByVal ClientID As String, Optional ByVal Code As WsCloseCode = WS_CLOSE_NORMAL, Optional ByVal Reason As String = "")
    On Error GoTo EH
    
    m_WsServer.DisconnectClient ClientID, Code, Reason
    LogMessage "Disconnected client " & ClientID
    Exit Sub

EH:
    LogMessage "Disconnect client failed: " & Err.Description
End Sub

Getting Client Information

vb
Private Sub GetClientInfo(ByVal ClientID As String)
    Dim oClient As cWebSocketServerClient
    
    Set oClient = m_WsServer.GetClient(ClientID)
    
    If Not oClient Is Nothing Then
        LogMessage "Client ID: " & oClient.ID
        LogMessage "Remote Address: " & oClient.RemoteAddress
        LogMessage "Remote Port: " & oClient.RemotePort
        LogMessage "Connection Time: " & oClient.ConnectedTime
    End If
End Sub

Complete Example

Refer to Server/frmServer.frm file:

vb
Private Sub cmdStart_Click()
    On Error GoTo EH

    If m_WsServer Is Nothing Then
        Set m_WsServer = New cWebSocketServer
    End If

    m_WsServer.Listen CLng(txtPort.Text)

    LogMessage "WebSocket server started, listening on port: " & txtPort.Text
    cmdStart.Enabled = False
    cmdStop.Enabled = True
    Exit Sub
EH:
    LogMessage "Service start failed: " & Err.Description
End Sub

Private Sub m_WsServer_OnClientTextMessage(ByVal ClientID As String, ByVal Message As String)
    LogMessage "Received text message from " & ClientID & ": " & Message

    ' Echo message
    m_WsServer.SendText ClientID, "Server received: " & Message

    ' If message is "broadcast", broadcast to all clients
    If LCase$(Message) = "broadcast" Then
        m_WsServer.BroadcastText "This is a broadcast message from client " & ClientID, ClientID
        LogMessage "Broadcast message sent to all clients"
    End If
End Sub

API Reference

cWebSocketClient Properties

PropertyTypeDescription
StateWsStateConnection state (see state constants)
URLStringConnected WebSocket URL
ReadyStateWsStateReadyState property (same as State)

cWebSocketClient Methods

Connect

vb
m_WsClient.Connect URL

Connects to WebSocket server.

Parameters:

  • URL: WebSocket server URL

SendText

vb
m_WsClient.SendText Message

Sends text message.

Parameters:

  • Message: Text message content

SendBinary

vb
m_WsClient.SendBinary Data()

Sends binary message.

Parameters:

  • Data: Byte array

Ping

vb
m_WsClient.Ping [Data()]

Sends Ping frame.

Parameters:

  • Data: Optional, additional data

CloseConnection

vb
m_WsClient.CloseConnection [Code], [Reason]

Closes connection.

Parameters:

  • Code: Optional, close code (default WS_CLOSE_NORMAL)
  • Reason: Optional, close reason

cWebSocketServer Methods

Listen

vb
m_WsServer.Listen Port

Starts listening on specified port.

Parameters:

  • Port: Listening port number

StopServer

vb
m_WsServer.StopServer

Stops service and disconnects all clients.

SendText

vb
m_WsServer.SendText ClientID, Message

Sends text message to specified client.

Parameters:

  • ClientID: Client ID
  • Message: Text message content

SendBinary

vb
m_WsServer.SendBinary ClientID, Data()

Sends binary message to specified client.

Parameters:

  • ClientID: Client ID
  • Data: Byte array

BroadcastText

vb
m_WsServer.BroadcastText Message, [ExcludeClientID]

Broadcasts text message to all clients.

Parameters:

  • Message: Text message content
  • ExcludeClientID: Optional, client ID to exclude

BroadcastBinary

vb
m_WsServer.BroadcastBinary Data(), [ExcludeClientID]

Broadcasts binary message to all clients.

Parameters:

  • Data: Byte array
  • ExcludeClientID: Optional, client ID to exclude

DisconnectClient

vb
m_WsServer.DisconnectClient ClientID, [Code], [Reason]

Disconnects specified client.

Parameters:

  • ClientID: Client ID
  • Code: Optional, close code
  • Reason: Optional, close reason

GetClient

vb
Set oClient = m_WsServer.GetClient(ClientID)

Gets client object.

Parameters:

  • ClientID: Client ID

Returns: cWebSocketServerClient object

State Constants

ConstantValueDescription
WS_STATE_CONNECTING0Connecting
WS_STATE_OPEN1Connected
WS_STATE_CLOSING2Closing
WS_STATE_CLOSED3Closed

Event Reference

Client Events

OnOpen

vb
Private Sub m_WsClient_OnOpen()

Triggered when connection is successfully established.

OnClose

vb
Private Sub m_WsClient_OnClose(ByVal Code As WsCloseCode, ByVal Reason As String)

Triggered when connection is closed.

Parameters:

  • Code: Close code
  • Reason: Close reason

OnTextMessage

vb
Private Sub m_WsClient_OnTextMessage(ByVal Message As String)

Triggered when text message is received.

Parameters:

  • Message: Text message content

OnBinaryMessage

vb
Private Sub m_WsClient_OnBinaryMessage(Data() As Byte)

Triggered when binary message is received.

Parameters:

  • Data: Binary data array

OnError

vb
Private Sub m_WsClient_OnError(ByVal Description As String)

Triggered when an error occurs.

Parameters:

  • Description: Error description

OnPong

vb
Private Sub m_WsClient_OnPong(Data() As Byte)

Triggered when Pong response is received.

Parameters:

  • Data: Pong data

Server Events

OnStart

vb
Private Sub m_WsServer_OnStart(ByVal Port As Long)

Triggered when service starts.

Parameters:

  • Port: Listening port number

OnStop

vb
Private Sub m_WsServer_OnStop()

Triggered when service stops.

OnClientConnect

vb
Private Sub m_WsServer_OnClientConnect(ByVal ClientID As String, ByVal RemoteAddress As String, ByVal RemotePort As Long)

Triggered when new client connects.

Parameters:

  • ClientID: Client ID
  • RemoteAddress: Client IP address
  • RemotePort: Client port

OnClientDisconnect

vb
Private Sub m_WsServer_OnClientDisconnect(ByVal ClientID As String, ByVal Reason As String)

Triggered when client disconnects.

Parameters:

  • ClientID: Client ID
  • Reason: Disconnect reason

OnClientTextMessage

vb
Private Sub m_WsServer_OnClientTextMessage(ByVal ClientID As String, ByVal Message As String)

Triggered when text message is received from client.

Parameters:

  • ClientID: Client ID
  • Message: Text message content

OnClientBinaryMessage

vb
Private Sub m_WsServer_OnClientBinaryMessage(ByVal ClientID As String, Data() As Byte)

Triggered when binary message is received from client.

Parameters:

  • ClientID: Client ID
  • Data: Binary data array

OnError

vb
Private Sub m_WsServer_OnError(ByVal Description As String)

Triggered when an error occurs.

Parameters:

  • Description: Error description

Advanced Features

Client Auto-reconnect

Implement client auto-reconnection mechanism:

vb
Private WithEvents tmrReconnect As Timer
Private lReconnectAttempts As Long

Private Sub m_WsClient_OnClose(ByVal Code As WsCloseCode, ByVal Reason As String)
    LogMessage "Connection closed: " & Reason
    
    ' Attempt reconnection on abnormal close
    If Code <> WS_CLOSE_NORMAL Then
        StartReconnectTimer
    End If
End Sub

Private Sub StartReconnectTimer()
    lReconnectAttempts = 0
    Set tmrReconnect = New Timer
    tmrReconnect.Interval = 3000  ' Reconnect after 3 seconds
    tmrReconnect.Enabled = True
End Sub

Private Sub tmrReconnect_Timer()
    tmrReconnect.Enabled = False
    
    If lReconnectAttempts < 5 Then
        lReconnectAttempts = lReconnectAttempts + 1
        LogMessage "Attempting to reconnect (" & lReconnectAttempts & "/5)..."
        m_WsClient.Connect txtURL.Text
    Else
        LogMessage "Reconnection failed, maximum attempts reached"
    End If
End Sub

Heartbeat Keep-alive

Implement heartbeat keep-alive for both client and server:

vb
' Client side
Private WithEvents tmrHeartbeat As Timer

Private Sub m_WsClient_OnOpen()
    LogMessage "Connected, starting heartbeat"
    
    Set tmrHeartbeat = New Timer
    tmrHeartbeat.Interval = 30000  ' 30 seconds
    tmrHeartbeat.Enabled = True
End Sub

Private Sub tmrHeartbeat_Timer()
    If m_WsClient.State = WS_STATE_OPEN Then
        m_WsClient.Ping
        LogMessage "Heartbeat Ping sent"
    End If
End Sub

' Server side - record last activity time
Private Sub m_WsServer_OnClientTextMessage(ByVal ClientID As String, ByVal Message As String)
    ' Record client activity time
    Dim oClient As cWebSocketServerClient
    Set oClient = m_WsServer.GetClient(ClientID)
    If Not oClient Is Nothing Then
        oClient.LastActivity = Now
    End If
End Sub

Message Queue

Implement message queue to ensure message order:

vb
Private colMessageQueue As Collection
Private bSending As Boolean

Private Sub InitializeQueue()
    Set colMessageQueue = New Collection
    bSending = False
End Sub

Private Sub EnqueueMessage(sMessage As String)
    colMessageQueue.Add sMessage
    
    If Not bSending Then
        ProcessQueue
    End If
End Sub

Private Sub ProcessQueue()
    If colMessageQueue.Count > 0 And m_WsClient.State = WS_STATE_OPEN Then
        bSending = True
        
        ' Get first message from queue
        Dim sMessage As String
        sMessage = colMessageQueue(1)
        colMessageQueue.Remove 1
        
        ' Send message
        m_WsClient.SendText sMessage
    Else
        bSending = False
    End If
End Sub

Private Sub m_WsClient_OnTextMessage(ByVal Message As String)
    LogMessage "Received response: " & Message
    
    ' Process next message
    If colMessageQueue.Count > 0 Then
        ProcessQueue
    Else
        bSending = False
    End If
End Sub

Authentication Mechanism

Implement simple token authentication:

vb
' Server - validate on connection
Private Sub m_WsServer_OnClientConnect(ByVal ClientID As String, ByVal RemoteAddress As String, ByVal RemotePort As Long)
    Dim oClient As cWebSocketServerClient
    Set oClient = m_WsServer.GetClient(ClientID)
    
    ' Check token in query parameters
    Dim sToken As String
    sToken = ExtractTokenFromClient(oClient)
    
    If Not IsValidToken(sToken) Then
        LogMessage "Authentication failed, disconnecting client: " & ClientID
        m_WsServer.DisconnectClient ClientID, WS_CLOSE_POLICY_VIOLATION, "Invalid token"
        Exit Sub
    End If
    
    LogMessage "Client authenticated successfully: " & ClientID
End Sub

' Client - attach token in URL
Private Sub ConnectWithToken(ByVal sURL As String, ByVal sToken As String)
    Dim sURLWithToken As String
    sURLWithToken = sURL & "?token=" & sToken
    
    m_WsClient.Connect sURLWithToken
End Sub

Message Compression

Use Deflate algorithm to compress messages:

vb
Private Sub SendCompressedMessage(sMessage As String)
    Dim byOriginal() As Byte
    Dim byCompressed() As Byte
    
    ' Convert to UTF-8 byte array
    byOriginal = UTF8.GetBytes(sMessage)
    
    ' Compress data (need to implement Deflate compression function)
    byCompressed = CompressData(byOriginal)
    
    ' Send compressed data
    m_WsClient.SendBinary byCompressed
    LogMessage "Sent compressed message: " & (UBound(byOriginal) + 1) & " -> " & (UBound(byCompressed) + 1) & " bytes"
End Sub

FAQ

Q1: How to handle connection timeout?

A: Use a timer to monitor connection state:

vb
Private WithEvents tmrConnect As Timer

Private Sub StartConnectTimer()
    Set tmrConnect = New Timer
    tmrConnect.Interval = 10000  ' 10 second timeout
    tmrConnect.Enabled = True
End Sub

Private Sub tmrConnect_Timer()
    tmrConnect.Enabled = False
    
    If m_WsClient.State = WS_STATE_CONNECTING Then
        LogMessage "Connection timeout"
        m_WsClient.CloseConnection WS_CLOSE_ABNORMAL, "Connection timeout"
        UpdateUI False
    End If
End Sub

Private Sub m_WsClient_OnOpen()
    tmrConnect.Enabled = False
    LogMessage "Connection successful"
End Sub

Q2: How to handle large messages?

A: Use message chunking:

vb
Private Sub SendLargeMessage(sMessage As String)
    Const MAX_CHUNK_SIZE As Long = 1024  ' 1KB chunk
    Dim lLength As Long
    Dim lOffset As Long
    Dim sChunk As String
    
    lLength = Len(sMessage)
    lOffset = 1
    
    Do While lOffset <= lLength
        sChunk = Mid(sMessage, lOffset, MAX_CHUNK_SIZE)
        m_WsClient.SendText sChunk
        
        LogMessage "Sent chunk " & (lOffset \ MAX_CHUNK_SIZE + 1) & ": " & Len(sChunk) & " bytes"
        lOffset = lOffset + MAX_CHUNK_SIZE
        
        ' Short delay
        DoEvents
        Sleep 50
    Loop
End Sub

Q3: How to limit client connections?

A: Maintain client count on server:

vb
Private lMaxClients As Long
Private lCurrentClients As Long

Private Sub InitializeServer()
    lMaxClients = 100  ' Maximum client count
    lCurrentClients = 0
End Sub

Private Sub m_WsServer_OnClientConnect(ByVal ClientID As String, ByVal RemoteAddress As String, ByVal RemotePort As Long)
    If lCurrentClients >= lMaxClients Then
        LogMessage "Connection rejected: maximum client count reached"
        m_WsServer.DisconnectClient ClientID, WS_CLOSE_TRY_AGAIN_LATER, "Server full"
        Exit Sub
    End If
    
    lCurrentClients = lCurrentClients + 1
    LogMessage "Client connection: " & ClientID & " (current: " & lCurrentClients & "/" & lMaxClients & ")"
End Sub

Private Sub m_WsServer_OnClientDisconnect(ByVal ClientID As String, ByVal Reason As String)
    lCurrentClients = lCurrentClients - 1
    LogMessage "Client disconnect: " & ClientID & " (current: " & lCurrentClients & ")"
End Sub

Q4: How to implement room functionality?

A: Use client grouping:

vb
Private colRooms As Collection

Private Sub InitializeRooms()
    Set colRooms = New Collection
End Sub

' Join room
Private Sub JoinRoom(ByVal ClientID As String, ByVal sRoom As String)
    Dim colClients As Collection
    
    On Error Resume Next
    Set colClients = colRooms(sRoom)
    
    If colClients Is Nothing Then
        Set colClients = New Collection
        colRooms.Add colClients, sRoom
    End If
    
    On Error GoTo 0
    colClients.Add ClientID, ClientID
    LogMessage "Client " & ClientID & " joined room: " & sRoom
End Sub

' Send to room
Private Sub SendToRoom(ByVal sRoom As String, ByVal sMessage As String)
    Dim colClients As Collection
    Dim i As Long
    
    On Error Resume Next
    Set colClients = colRooms(sRoom)
    On Error GoTo 0
    
    If Not colClients Is Nothing Then
        For i = 1 To colClients.Count
            m_WsServer.SendText colClients(i), sMessage
        Next i
    End If
End Sub

Q5: How to debug WebSocket communication?

A: Record all events and detailed logs:

vb
Private Sub LogWebSocketEvent(ByVal sEventType As String, ByVal sDetails As String)
    Dim sLog As String
    sLog = Format$(Now, "yyyy-mm-dd hh:mm:ss") & " [" & sEventType & "] " & sDetails
    
    ' Output to log window
    txtLog.Text = txtLog.Text & sLog & vbCrLf
    txtLog.SelStart = Len(txtLog.Text)
    
    ' Output to debug window
    Debug.Print sLog
    
    ' Optional: write to file
    LogToFile sLog
End Sub

Private Sub LogToFile(sLog As String)
    Dim nFile As Integer
    nFile = FreeFile
    
    Open App.Path & "\websocket.log" For Append As #nFile
    Print #nFile, sLog
    Close #nFile
End Sub

Best Practices

  1. Resource cleanup: Call CloseConnection or StopServer when form unloads to release resources
  2. Error handling: Include error handling for all network operations
  3. State checking: Check State = WS_STATE_OPEN before sending messages
  4. Logging: Record key events for easier debugging and troubleshooting
  5. Timeout handling: Implement reasonable connection and operation timeouts
  6. Heartbeat keep-alive: Periodically send Ping frames to keep connection active
  7. Message validation: Validate format and length when receiving messages
  8. Graceful shutdown: Use correct close codes and reason information
  9. Client limiting: Implement reasonable client connection limits
  10. Security authentication: Implement authentication mechanisms in production environments

Protocol Specification

WebSocket Handshake Process

  1. Client Request
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
  1. Server Response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Frame Structure

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |           Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

Opcodes

ValueDescription
0x0Continuation frame
0x1Text frame
0x2Binary frame
0x8Close frame
0x9Ping frame
0xAPong frame

  • Project directory: Websocket/
  • Client example: Client/frmClient.frm
  • Server example: Server/frmServer.frm
  • Dependency library: VBMAN.dll
  • WebSocket Protocol: RFC 6455

Changelog

  • v2.0 - New library version, separated client/server, optimized architecture
    • Separated client (cWebSocketClient) and server (cWebSocketServer) classes
    • Independent frame parser (cWebSocketFrame)
    • Efficient buffer management (cByteBuffer)
    • Clear separation of concerns and error handling
  • v1.0 - Initial version

VB6 and LOGO copyright of Microsoft Corporation