Skip to content

cWinsock User Binding and Group Management

Feature Overview

User binding and group management features provide a complete user identity management and message distribution mechanism:

  • User Binding: Associate user identity with socket connection, support sending messages by username
  • Group Management: Group users for batch message sending and management operations
  • Bidirectional Sync: Group operations automatically sync server-side and client-side CurrentGroups
  • Auto Cleanup: Automatically unbind when user disconnects, no manual handling needed

Key Properties

PropertyTypeDescription
CurrentUserVariantUsername bound to client instance
CurrentUserTokenStringUser token bound to client instance (e.g., auth token)
CurrentUserInfocJsonUser extended info bound to client instance (JSON object)
CurrentGroupsDictionaryGroup list client belongs to (group name → True)

User Binding

BindUser Method

Description

Binds a user to a client connection, achieving association between user identity and socket connection.

Syntax

vb
Public Sub BindUser(ByVal User As Variant, Client As cWinsock, Optional ByVal Token As String, Optional Info As cJson)

Parameters

ParameterTypeDescription
UserVariantUser identifier (string or other unique value)
ClientcWinsockClient socket instance
TokenString (optional)User auth token, can be retrieved via Client.CurrentUserToken after binding
InfocJson (optional)User extended info (JSON object), can be retrieved via Client.CurrentUserInfo after binding

Usage Example

vb
' Server: Bind user when client connects
Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    
    ' Parse login message, format: "LOGIN:username"
    If Left$(sData, 6) = "LOGIN:" Then
        Dim sUsername As String
        sUsername = Mid$(sData, 7)
        
        ' Bind user to client (with Token and extended info)
        Dim oInfo As New cJson
        oInfo.Add "loginTime", Now
        oInfo.Add "ip", Client.RemoteHostIP
        m_oServer.BindUser sUsername, Client, "secret_token_123", oInfo
        
        Client.SendData "LOGIN:OK"
        Debug.Print "User " & sUsername & " logged in, Token: " & Client.CurrentUserToken
    End If
End Sub

ExistsUser Method

Description

Check if specified user is bound.

Syntax

vb
Public Function ExistsUser(ByVal User As Variant) As Boolean

Usage Example

vb
If m_oServer.ExistsUser("alice") Then
    Debug.Print "User is online"
Else
    Debug.Print "User is offline"
End If

UnbindUser Method

Description

Unbind specified user.

Syntax

vb
Public Sub UnbindUser(ByVal User As Variant)

Usage Example

vb
' Manually kick user
If m_oServer.ExistsUser("alice") Then
    m_oServer.UnbindUser "alice"
    Debug.Print "User unbound"
End If

Auto Unbind

When user disconnects, system automatically removes from user list, no manual call needed.


SendToUser Method

Description

Send data to bound user.

Syntax

vb
Public Sub SendToUser(ByVal User As Variant, Data As Variant, Optional ByVal CodePage As EnumScpCodePage = wcpAcp)

Parameters

ParameterTypeDescription
UserVariantUser identifier
DataVariantData to send (string or byte array)
CodePageEnumScpCodePage (optional)Text encoding, default wcpAcp

Usage Example

vb
' Send message to specific user
m_oServer.SendToUser "alice", "Hello, Alice!"

' Send with UTF-8 encoding
m_oServer.SendToUser "alice", "Hello, Alice!", wcpUtf8

' Broadcast message to all online users
Dim vUser As Variant
For Each vUser In m_oServer.m_Users.Keys
    m_oServer.SendToUser vUser, "System announcement: Server maintenance in 5 minutes"
Next

Error Handling

If user doesn't exist, error is thrown:

vb
On Error GoTo EH
m_oServer.SendToUser "bob", "Hello!"
Exit Sub
EH:
If Err.Number = vbObjectError Then
    MsgBox "User is offline"
End If

Group Management

Group management allows grouping users for easy batch message sending and management.

Prerequisites

Before binding to a group, user must first bind to client:

vb
' ✅ Correct flow: Bind user first, then bind to group
m_oServer.BindUser "alice", Client
m_oServer.BindGroup "admins", Client

' ❌ Wrong: User not bound, cannot bind to group
m_oServer.BindGroup "admins", Client  ' Will error

BindGroup Method

Description

Add client with bound user to specified group.

Syntax

vb
Public Sub BindGroup(ByVal GroupName As String, Client As cWinsock)

Parameters

ParameterTypeDescription
GroupNameStringGroup name
ClientcWinsockClient instance with bound user

Usage Example

vb
Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    
    ' Parse join group request, format: "JOIN_GROUP:groupname"
    If Left$(sData, 11) = "JOIN_GROUP:" Then
        Dim sGroup As String
        sGroup = Mid$(sData, 12)
        
        ' Check if user is bound
        If LenB(CStr(Client.CurrentUser)) = 0 Then
            Client.SendData "ERROR: Please login first"
            Exit Sub
        End If
        
        ' Join group
        m_oServer.BindGroup sGroup, Client
        Client.SendData "JOIN_GROUP:OK:" & sGroup
        Debug.Print Client.CurrentUser & " joined group: " & sGroup
    End If
End Sub

Multiple Joins to Same Group

Same user can call BindGroup multiple times for same group, but won't be added duplicate times.


ExistsGroup Method

Description

Check if specified group exists.

Syntax

vb
Public Function ExistsGroup(ByVal GroupName As String) As Boolean

Usage Example

vb
If m_oServer.ExistsGroup("admins") Then
    Debug.Print "Admin group exists, member count: " & m_oServer.GetGroupMembers("admins").Count
Else
    Debug.Print "Admin group doesn't exist"
End If

UnbindGroup Method

Description

Remove user from specified group.

Syntax

vb
Public Sub UnbindGroup(ByVal GroupName As String, ByVal User As Variant)

Usage Example

vb
' Remove user from group
m_oServer.UnbindGroup "admins", "alice"

' Group leader kicks user
Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    
    If Left$(sData, 13) = "KICK_FROM_GROUP" Then
        Dim sGroup As String, sTarget As String
        sGroup = Mid$(sData, 14, InStr(sData, ":") - 14)
        sTarget = Mid$(sData, InStr(sData, ":") + 1)
        
        m_oServer.UnbindGroup sGroup, sTarget
        Debug.Print sTarget & " removed from group: " & sGroup
    End If
End Sub

Auto Cleanup

When all members leave a group, the group is automatically deleted.


GetGroupMembers Method

Description

Get list of all member usernames in specified group.

Syntax

vb
Public Function GetGroupMembers(ByVal GroupName As String) As String()

Return Value

Returns string array containing all member usernames. Returns empty array if group doesn't exist or is empty.

Usage Example

vb
Dim aMembers() As String
Dim sMember As String

aMembers = m_oServer.GetGroupMembers("admins")

If UBound(aMembers) >= 0 Then
    Debug.Print "Admin group has " & (UBound(aMembers) + 1) & " members:"
    For Each sMember In aMembers
        Debug.Print "  - " & sMember
    Next
Else
    Debug.Print "Admin group is empty"
End If

SendToGroup Method

Description

Send data to all members in specified group.

Syntax

vb
Public Sub SendToGroup(ByVal GroupName As String, Data As Variant, Optional ByVal CodePage As EnumScpCodePage = wcpAcp)

Parameters

ParameterTypeDescription
GroupNameStringGroup name
DataVariantData to send
CodePageEnumScpCodePage (optional)Text encoding

Usage Example

vb
' Send group message
m_oServer.SendToGroup "developers", "Colleagues, tech sharing at 3pm today"

' Broadcast system announcement to all groups
Dim sGroup As Variant
For Each sGroup In m_oServer.m_Groups.Keys
    m_oServer.SendToGroup CStr(sGroup), "[System] Server will restart in 10 minutes"
Next

Smart Handling

  • If group doesn't exist, no data is sent
  • If some users in group are offline, they're automatically skipped, only online users receive

GetUserGroups Method

Description

Get list of all groups that specified user belongs to.

Syntax

vb
Public Function GetUserGroups(ByVal User As Variant) As String()

Return Value

Returns string array containing all group names.

Usage Example

vb
' View groups user belongs to
Dim aGroups() As String
Dim sGroup As String

aGroups = m_oServer.GetUserGroups("alice")

If UBound(aGroups) >= 0 Then
    Debug.Print "alice belongs to the following groups:"
    For Each sGroup In aGroups
        Debug.Print "  - " & sGroup
    Next
Else
    Debug.Print "alice is not in any groups"
End If

DeleteGroup Method

Description

Disband specified group, synchronously deletes the group from all members' CurrentGroups.

Syntax

vb
Public Sub DeleteGroup(ByVal GroupName As String)

Usage Example

vb
' Disband group
m_oServer.DeleteGroup "temp_group"
Debug.Print "Group disbanded"

' Admin disbands group
Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    
    If Left$(sData, 12) = "DELETE_GROUP" Then
        Dim sGroup As String
        sGroup = Mid$(sData, 14)
        
        If m_oServer.ExistsGroup(sGroup) Then
            m_oServer.DeleteGroup sGroup
            Debug.Print "Group " & sGroup & " has been disbanded"
        End If
    End If
End Sub

Sync Mechanism

When disbanding a group, system automatically iterates all group members, removing the group name from each member's CurrentGroups.


CloseUser Method

Description

Force specified user offline, close their client connection.

Syntax

vb
Public Sub CloseUser(ByVal User As Variant)

Usage Example

vb
' Kick specified user offline
m_oServer.CloseUser "alice"
Debug.Print "User offline"

' Admin kicks user
Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    
    If Left$(sData, 5) = "KICK:" Then
        Dim sTarget As String
        sTarget = Mid$(sData, 6)
        
        If m_oServer.ExistsUser(sTarget) Then
            m_oServer.CloseUser sTarget
            Debug.Print sTarget & " has been kicked by admin"
        End If
    End If
End Sub

Cleanup Flow

Calling CloseUser triggers client's Class_Terminate, automatically completing the following cleanup:

  • Unbind from all groups
  • Remove from user list
  • Clear CurrentGroups

Internal Methods

The following methods are for internal use, usually don't need to be called directly:

UnbindUserFromAllGroups

Unbind user from all groups (called by Class_Terminate, automatically triggered when user disconnects). Syncs client CurrentGroups.


Data Structure and Sync Mechanism

Server-side Storage Structure

m_Users (Dictionary)
  └── Username → cWinsock client instance

m_Groups (Dictionary)
  └── Group name → Dictionary(Username → True)

Client Instance Properties

CurrentUser (Variant)
  └── Bound username

CurrentUserToken (String)
  └── User auth token (Token passed when BindUser)

CurrentUserInfo (cJson)
  └── User extended info (Info passed when BindUser)

CurrentGroups (Dictionary)
  └── Group name → True

Bidirectional Sync

All group operations automatically sync server-side and client-side data:

OperationServer-sideClient-side
BindGroupAdd to m_Groups[groupName]Add to CurrentGroups
UnbindGroupRemove from m_Groups[groupName]Remove from CurrentGroups
DeleteGroupDelete m_Groups[groupName]Remove from all members' CurrentGroups
UnbindUserFromAllGroupsRemove user from all groupsClear CurrentGroups

Auto Cleanup Mechanism

Cleanup Flow When User Disconnects

When client disconnects, system automatically executes the following cleanup:

1. Client Close_() or Class_Terminate() is called
2. Check if CurrentUser is empty
3. If not empty:
   a. Call UnbindUserFromAllGroups() to remove from all groups
   b. Call UnbindUser() to remove from user list
   c. Clear CurrentGroups
   d. Clear CurrentUser
   e. Clear CurrentUserToken (set to empty string)
   f. Clear CurrentUserInfo (call Clear)

Memory Management Notes

User binding uses Dictionary to store user and group references. To avoid memory leaks:

  1. Always bind/unbind through server object: Don't directly operate internal m_Users and m_Groups
  2. Use RemoveClient: Should call server's RemoveClient method when client disconnects
  3. Avoid circular references: Server holds client reference, client holds parent server reference (via ParentServer)

Complete Chat Server Example

vb
' Complete server-side example
Dim WithEvents m_oServer As cWinsock

Private Sub Form_Load()
    Set m_oServer = New cWinsock
    m_oServer.Protocol = sckTCPProtocol
    m_oServer.Listen 8080
End Sub

' Handle connection request
Private Sub m_oServer_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)
    Debug.Print "New connection: " & Client.RemoteHostIP
End Sub

' Handle data arrival
Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    
    ' Parse command
    Select Case Left$(sData, InStr(sData, ":") - 1)
        Case "LOGIN"
            HandleLogin Client, Mid$(sData, 7)
            
        Case "JOIN_GROUP"
            HandleJoinGroup Client, Mid$(sData, 12)
            
        Case "MSG"
            HandleMessage Client, Mid$(sData, 5)
            
        Case "BROADCAST"
            HandleBroadcast Client, Mid$(sData, 11)
    End Select
End Sub

Private Sub HandleLogin(Client As cWinsock, ByVal sUsername As String)
    If m_oServer.ExistsUser(sUsername) Then
        Client.SendData "LOGIN:ERROR:User already logged in"
        Exit Sub
    End If
    
    ' Bind user, with Token and extended info
    Dim oInfo As New cJson
    oInfo.Add "loginTime", Now
    oInfo.Add "ip", Client.RemoteHostIP
    m_oServer.BindUser sUsername, Client, "secret_token_123", oInfo
    
    Client.SendData "LOGIN:OK"
    Debug.Print sUsername & " logged in, Token: " & Client.CurrentUserToken
End Sub

Private Sub HandleJoinGroup(Client As cWinsock, ByVal sGroup As String)
    If LenB(CStr(Client.CurrentUser)) = 0 Then
        Client.SendData "ERROR:Please login first"
        Exit Sub
    End If
    
    m_oServer.BindGroup sGroup, Client
    Client.SendData "JOIN_GROUP:OK:" & sGroup
    Debug.Print Client.CurrentUser & " joined group: " & sGroup
End Sub

Private Sub HandleMessage(Client As cWinsock, ByVal sMsg As String)
    If LenB(CStr(Client.CurrentUser)) = 0 Then
        Client.SendData "ERROR:Please login first"
        Exit Sub
    End If
    
    ' Send message to all group members
    m_oServer.SendToGroup "general", Client.CurrentUser & ": " & sMsg
End Sub

Private Sub HandleBroadcast(Client As cWinsock, ByVal sMsg As String)
    If LenB(CStr(Client.CurrentUser)) = 0 Then
        Client.SendData "ERROR:Please login first"
        Exit Sub
    End If
    
    ' Broadcast to all groups
    Dim sGroup As Variant
    For Each sGroup In m_oServer.m_Groups.Keys
        m_oServer.SendToGroup CStr(sGroup), "[Broadcast] " & Client.CurrentUser & ": " & sMsg
    Next
End Sub

' Handle client disconnect
Private Sub m_oServer_CloseEvent(Client As cWinsock)
    If LenB(CStr(Client.CurrentUser)) <> 0 Then
        Debug.Print Client.CurrentUser & " is offline"
        ' No need to manually unbind, system handles automatically
    End If
End Sub

Last Updated: 2026-04-26

VB6 and LOGO copyright of Microsoft Corporation