VBWebsocket Help File

Introduction

VBWebsocket is a client side websocket implemented as a VB6 UserControl, and is the first open VB6 client websocket UserControl implementation to support both standard and secure connections using SSL/TLS. The API loosely follows the Java implementation and code flow. It currently supports websocket protocol 13 as specified in the rfc6455 of the websocket standard. Some accomodations were made for servers that use none-standard behavior but are mostly industry wide accepted practices. It is presented as Open Source for a starting point to implement your own as needed or can be easily used as is. Each VBWebsocket instance represents 1 connection to a websocket server. Multiple connections can be made by using control arrays or citing several VBWebsocket controls on your form as needed. Or if you're feeling motivated the source code could be altered to support multiple connections.

Best practices would suggest that you use the code in your project without compiling to ocx to avoid collisions with other possibly compiled VBWebsocket ocx controls by someone else. If you choose to compile to ocx you should rename it to something else besides VBWebsocket.ocx. Also keeping the ocx in your app folder will help avoid collisions. The files you will need to include in your project are the exact same ones included in the project example.

This help file is in a state of flux and will probably change in the future with additions and edits.

Credits

VBWebsocket uses technology developed by Vladimir Vissoultchev aka wqweto (wqweto@gmail.com) from his VBAsyncSocket project for a SSL/TLS socket implementation. Some code contributions were translated from a chinese blog site by a user named Youran (ur1986@foxmail.com) at https://www.cnblogs.com/xiii/p/7135233.html. This project would not have been possible without thier contributions. As noted previously, the rfc standard rfc6455 was followed. Some code from DI Systems website was followed for UTF8 encoding in VB6. Most of the code in mWebsocket.bas and Websocket.ctl was created or heavily modified by the author (me). Also a vbForums user named Maatooh created the first VB6 class based secure websocket, see the link below for his project.

If you find any bugs, errors, or have suggestions or comments please feel free to email me at dethbomb@hotmail.com or visit the vbforums post.

Links

VBForums VBWebsocket Post:
https://www.vbforums.com/showthread.php?892835-VB6-Visual-Basic-6-Client-Websocket-Control

Websocket Protocol Standard
https://www.rfc-editor.org/rfc/rfc6455.txt

Deflate Compression Standard
https://www.rfc-editor.org/rfc/rfc7692.txt

wqweto VBAsyncSocket Project
https://github.com/wqweto/VbAsyncSocket

IANA Websocket Registry
https://www.iana.org/assignments/websocket/websocket.xml

Maatooh VB6 WSS Websocket project
https://github.com/Maatooh/TlsSocketWSS-vb6

Index

Methods
Events
Enums
Properties
Connect
DisConnect
Send
GetStatusCodeText
Ping
SendAdvanced
onMessage
onError
onConnect
onClose
onProgress
onPong
onReConnect
WebSocketStatus
WebsocketState
WebsocketOpCode
readyState
Protocols
UseCompression
isBusy
Extensions
ChunkSize











METHODS

Public Sub Connect(ByVal Uri As String, Optional ByVal Port As String, Optional ByVal SubProtocols As String, Optional ByVal ProtocolExtensions As String, Optional Headers As Collection)

The Connect method is used to initiate a connection to a websocket server. example: ws.Connect("wss://echo.websocket.org")

Arguments
Required
Type
Description
Uri
required
String
The URI (aka URL) of the websocket server. This should be in the form of:
ws[s]://serveraddress.com[:port][/path][?param=value]
(items in brackets are optional) if the server is a SSL connection you should use wss:// and port 443, if its a non-secure connection you should use ws:// and port 80 (or the port required by the server)
[Port]
optional
String
if the port isnt specified in the url then you can pass a port with this parameter. If no ports are specified VBWebsocket uses port 80 for ws:// urls and port 443 for wss:// urls. A port specified in the URL overrides all other ports specified.
[SubProtocols]
optional
String
Use this parameter to specify the desired high level protocol(s) you want to use. Use a string in a CSV (comma separated values) format aka "MQTT, WAMP, JSON". After connection check the Protocols property to see which protocols the server accepted.
[ProtocolExtensions]
optional
String
Use this parameter to specify the desired Protocol extension(s) you want to use. Use a string in a CSV (comma separated values) format aka "permessage-deflate, bbf-usp-protocol". Note: the compression extension is handled internally by the websocket. Use the UseCompression property before connecting to enable. Check the IANA websocket registry page for official extensions.
[Headers]
optional
Collection
This is a collection of additional optional header lines such as "Content-Type: application/json". Specify only the header line, VBWebsocket takes care of any formatting such as adding line feeds. See the piesocket example in the sample code for an example useage.


Public Sub Disconnect()

Use this method to disconnect from a websocket server. example: ws.Disconnect


Public Function GetStatusCodeText(ByVal statCode As WebsocketStatus) As String

Use this to get a friendly error message from a status code or error number. Most times this will be the same as reason parameter in the onError event (unless it is a winsock error).

Arguments
Required
Type
Description
statcode
required
WebSocketStatus
This can be a value from the WebSocketStatus enum or a Long error value.


Public Sub Send(ByVal Data As Variant, Optional ByVal NoUTF8Conversion As Boolean)

Use this method to send data to a websocket server. ex: ws.Send("Hello World!")
By default VBWebsocket now sends everything as Text. If you need to send as Binary, use a Byte Array. If you use a byte array VBWebsocket will automatically send the Data as untouched binary data. If you send a String, VBWebsocket will send as Text encoded in UTF8. Use byte arrays for files, pictures, media objects etc. NEW: you can now send binary strings by setting the extra parameter NoUTF8Conversion to true. This allows you to use strings to load binary files instead of byte arrays. under the hood the websocket will convert your string to a byte array  (as-is not with strconv)  and send as binary.

Arguments
Required
Type
Description
Data
required
Variant
On most websocket servers this will be a string formatted as JSON, XML or plain text. The server you are connecting to, and the application layer protocol you agreed to, determines what and how the data is formatted before you send it. NOTE: This parameter has been changed from String to Variant to allow for sending Byte Arrays as a Binary websocket message. Use strings when sending formatted data such as JSON, XML or plain text, Use Byte Arrays when sending files, picture data, or media objects etc. By default VBWebsocket now sends all data as Text encoded in UTF8.
NoUTF8Conversion
Optional
Boolean
you can set this optional parameter to True if you want to send a string as binary without UTF8 encoding. Use this for sending Binary strings only such as those loaded from a file, this parameter has no effect on byte arrays. If you set this parameter to true and data is not a string an error will occur.



Public Sub SendAdvanced(ByVal Data As Variant, ByVal OpCode As Long, ByVal blnUTF8Encode As Boolean, Optional ByVal blnCompressData As Boolean, Optional ByVal blnSetFinBit As Boolean = True, Optional ByVal RSV1 As Boolean, Optional ByVal RSV2 As Boolean, Optional ByVal RSV3 As Boolean)

This procedure was added to allow for sending extension data. It gives you fine grained control over how the websocket message is constructed. Some of the same rules apply as the regular Send() function,for example: if you specify blnUTF8Encode then the data should be a text string (or a byte array directly assigned from a string) or else it will be treated as a binary string. Also if you specify compression you must have set the UseCompression option to true before connecting. If you specify compression then RSV1 will be set to true by the websocket. Also Data can only be a byte array or a string. Empty data can be sent.


Arguments
Required
Type
Description
Data
required
Variant
Byte Array or String data.
OpCode
required
Long
Specify the opCode. You can use the built in opCodes or an extension opCode 3-7, 11-15. any other opcode will cause an error.
blnUTF8Encode
optional
Boolean
Set to True if you wish to have the websocket encode the data in UTF8 for a String (or Textual) data. The websocket expects a String or Byte Array to be a Native VB6 String encoded in UTF16. If you specify any other type of data with this flag, the data will be corrupted.
blnCompressData
optional
Boolean
Set to True if you wish the websocket to compress the data before sending. You must have set UseCompression to true before connecting and the server must have accepted the compression extension in order to use compression. If you use this compression flag, the websocket will automatically set RSV1 to true. You can optionally compress the data yourself and set RSV1 to true if you wish.
blnSetFinBit
optional
Boolean
Set this to False if you dont want the FIN bit set. This is by default True. Normally you only set this to false on opContinue frames.
RSV1
optional
Boolean
This is normally reserved for compressed frames or messages. Set to true if data is already compressed. Do not set this if you specify the blnCompressData flag as the websocket will set this automatically.
RSV2
optional
Boolean
reserved for use by extensions
RSV3
optional
Boolean
reserved for use by extensions



Public Sub Ping(Optional ByVal ExtraMsg As String)

Ping the server, an option message can be included such as "Hello". If the server answers the onPong event will be raised.




EVENTS

Event onMessage(ByVal Msg As Variant)

This event happens when the server sends data to the websocket.

Parameters
Type
Description
Msg
Variant
On most websocket servers this will be a string formatted in JSON, XML or plain text. The server you are connecting to determines what and how the data is formatted before you recieve it. NOTE: this option has been changed from String to Variant in order to support multiple formats. If the server indicates that the Data is binary, Msg will contain a byte array, otherwise it will contain a string. Check the opCode parameter to see what type of data the message contains. You can also use the built in VarType(Msg) function to determine if Msg contains a byte array or string. See the sample code for an example.
opCode
WebsocketOpCode
If this parameter is opText - 1 the Msg parameter is a text string , if it is opBinary-2 it is a byte array. if it is 3-7 or 11-15 it is extension data and Msg is formatted in a raw untouched byte array(not decompressed either)


Event onConnect(ByVal RemoteHost As String, Byval RemoteIP as String, ByVal RemotePort As String)

This event occurrs whenever the websocket makes a successful connection to a websocket server.

Parameters
Type
Description
RemoteHost
String
The resolved remote host name of the websocket server you are connected to.
RemoteIP
String
The IP address of the remote host.
RemotePort
String
The remote port of the websocket server you are connected to.



Event onClose(ByVal eCode As WebsocketStatus, ByVal reason As String)

This event happens whenever the connection is closed to the remote server. eCode and reason will be the same as the onError event.

Parameters
Type
Description
eCode
WebsocketStatus
A error code generated by the server. You can use the function GetStatusCodeText(eCode) function to get an error description which is usually the same as reason. See the onError event for more descriptions of error codes and their meanings.
reason
String
A user friendly error description of the error that occurred. You can also use GetStatusCodeText function with the eCode to get a error description.



Event onError(ByVal eCode As WebsocketStatus, ByVal reason As String)

This event happens whenever an error occurs. eCode is the error number while reason is a friendly description of the error.

000-999     unused by websocket, an error in this range will most likely be an internal VB error, such as 5-invalid argument
1000-1015   standard websocket errors aka Close Codes
1016        trapped socket error
s
1017-1999   unused or OS (Windows) error
2000-2999   Websocket Extension errors
3000-3999   Library or Framework errors
4000-4999   Application Layer errors
5000-10000  unused or OS (Windows) error
> 10,000    untrapped Winsock errors

Parameters
Type
Description
eCode
WebsocketStatus
A error code generated by the websocket. This can also be an underlying winsock error. If code is 1016 (WebsocketStatus.WinsockError) then it is an internal socket or winsock error. You can use the function GetStatusCodeText(eCode) function to get an error description which is usually the same as reason.
reason
String
A user friendly error description of the error that occurred. You can also use GetStatusCodeText function with the eCode to get a error description.



Event onProgress(ByVal bytesSent As Long, ByVal bytesMax As Long, Cancel As Boolean)

This event occurrs whenever the websocket is making large data sends greater than 4kb to the server. You can set the byref Cancel parameter to True to cancel the send.
To get bytesRemaining use (bytesMax - bytesSent).
When bytesSent = bytesMax then the send is complete.

Parameters
Type
Description
bytesSent
Long
The number of bytes that have been sent in the current message
bytesMax
Long
the total number of bytes in the message
Cancel
Boolean
A byref parameter that you can set to True to cancel the send.

Event onPong(ByVal IncludedMsg As String)

This event happens when the server answers a Ping message from the websocket. Sometimes the server may include an extra message such as "Pong" or "Hello".

Parameters
Type
Description
IncludedMsg
String
The server may include an extra message such as "Pong" or "Hello" otherwise this will be an empty string.




Event onReConnect(ByVal newURI As String)

This event happens whenever the connection is redirected by the remote server in the HTTP Handshake. The parameter newURI will have the redirect url value. This lets you update the URI in the GUI for the user.

Parameters
Type
Description
newURI
String
The new Url that the connection is being directed to.






ENUMS


The WebsocketStatus enum is a list of error codes that are websocket specific. These are called Close codes because the connection is always closed after these errors.

Public Enum WebsocketStatus
  NormalClosure = 1000
  GoingAway = 1001
  ProtocolError = 1002
  UnsupportedData = 1003
  StatusReserved = 1004
  NoStatusReceived = 1005
  AbNormalClosure = 1006
  InvalidData = 1007
  PolicyViolation = 1008
  MessageToLarge = 1009
  MandatoryExtension = 1010
  InternalError = 1011
  ServiceRestart = 1012
  TryAgainLater = 1013
  BadGateWay = 1014
  SslTlsHandshake = 1015 
End Enum


The WebsocketState enum is a list of connection states the websocket is in. Check the readyState property to get current status.

Public Enum WebSocketState
    STATE_CLOSED

    STATE_OPEN
    STATE_CONNECTING
    STATE_CLOSING
End Enum




this enum defines the websocket operation codes aka op codes, op codes 3-7 and 11-15 are extension codes and data must be handled by the application, any other opcodes are invalid.

Public Enum WebsocketOpCode
     opContinue = 0   ' successive message frame
     opText = 1       ' text message frame
     opBinary = 2     ' binary message frame
     opClose = 8      ' connection closing
     OpPing = 9       ' ping heartbeat check
     opPong = 10      ' ping heartbeat answer
End Enum





PROPERTIES


(Read-Only) Property Get readyState() As WebSocketState

Read the readystate property for information on the current connection state of the websocket. See the WebsocketState enum for a list of possible values.


(Read-Only) Property Get Protocols() As String

Read this property to see what protocols the server has accepted from the SubProtocols you specified in the Connect method.


(Read-Only) Property Get Extensions() As String

Read this property to see what Extensions the server has accepted from the ProtocolExtensions you specified in the Connect method.


(Read-Write) Property Let/Get UseCompression() As Boolean

Set this property to send and recieve compressed data. Note that this is handled internally. You should not try to compress/decompress the data yourself (if you use this property), as it will result in data corruption.


(Read-Only) Property Get isBusy() As Boolean

If this property returns True, the websocket is in the middle of sending or receiving data.


(Read-Write) Property Let/Get ChunkSize() As Double

Set or read this property to get/set the chunk size of data that the websocket sends to the server. the websocket protocol specifies 3 sizes for sending a data frame, (1)0-125 bytes, (2)126-65535 bytes and (3)65536-2147483647(2.1 Gb) bytes.
The websocket protocol also allows for splitting up data into smaller chunks and sending in multiple split packets called continue frames.The chunk size determines at what size the websocket will split up the data into multiple data frames to send. For example lets say you are sending 41kb of data in one send and chunksize is 4kb. The websocket will split up the send into 10 - 4kb sends and the last packet will be the remaining 1kb. If you frequently send large packets you can fine tune the data chunk size to be more effecient knowing that most winsock frames are 16kb in size (4kb on older systems)..
This value should be an evenly divisible number (modulo) of 1024