Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

SGC Web Sockets

Download as pdf or txt
Download as pdf or txt
You are on page 1of 641

sgcWebSockets 

2022.2
February 2022

Documentation for Delphi

Copyright © 2012-2022 eSeGeCe.com


info@esegece.com
www.esegece.com
SGCWEBSOCKETS

Contents

Introduction.htm ................................................................................................ 14

Overview .............................................................................................................. 18

Editions.................................................................................................................................. 18
Installation ............................................................................................................................ 20

Install.................................................................................................................... 23

Install Package ...................................................................................................................... 23


Install Errors.......................................................................................................................... 30
Configure Install ................................................................................................................... 33
Install sgcIndy Package........................................................................................................ 35

QuickStart............................................................................................................ 36

Overview ............................................................................................................................... 36
QuickStart WebSockets ....................................................................................................... 38
QuickStart HTTP ................................................................................................................... 40
Threading Flow ..................................................................................................................... 42
Build....................................................................................................................................... 44
Build OSX Application .......................................................................................................... 45
Build Android Application ................................................................................................... 47
Build iOS Application ........................................................................................................... 48
Fast Performance Server..................................................................................................... 50
Memory Manager................................................................................................................. 52
OpenSSL ................................................................................................................................ 55
OpenSSL Windows ............................................................................................................... 57
OpenSSL OSX ........................................................................................................................ 58
OpenSSL Android ................................................................................................................. 60
OpenSSL iOS ......................................................................................................................... 61

ii
SGCWEBSOCKETS

Indy ........................................................................................................................................ 63

Topics ................................................................................................................... 64

WebSocket Events ................................................................................................................ 64


WebSocket Parameters Connection .................................................................................. 65
Using inside a DLL ................................................................................................................ 66
Web Browser Test ................................................................................................................ 67
Custom Sub-Protocols ......................................................................................................... 68
Authentication ...................................................................................................................... 71
Secure Connections ............................................................................................................. 73
HeartBeat .............................................................................................................................. 75
WatchDog.............................................................................................................................. 76

Logs........................................................................................................................................ 77
HTTP....................................................................................................................................... 78
Broadcast and Channels ..................................................................................................... 79
Bindings................................................................................................................................. 80
Post Big Files ......................................................................................................................... 81
Compression......................................................................................................................... 83
Flash....................................................................................................................................... 84
Custom Objects .................................................................................................................... 85
IOCP ....................................................................................................................................... 86
ALPN ...................................................................................................................................... 87
Forward HTTP Requests ...................................................................................................... 88
Quality Of Service................................................................................................................. 89
Queues .................................................................................................................................. 91
Transactions ......................................................................................................................... 93
TCP Connections .................................................................................................................. 94
SubProtocol .......................................................................................................................... 95
Throttle .................................................................................................................................. 96
Server-Sent Events ............................................................................................................... 97
LoadBalancing ...................................................................................................................... 99

iii
SGCWEBSOCKETS

Files ...................................................................................................................................... 100


Proxy .................................................................................................................................... 101
Fragmented Messages ...................................................................................................... 102

Components ...................................................................................................... 103

TsgcWebSocketClient.htm................................................................................................. 103
Connect WebSocket Server............................................................................................... 109
Client Open Connection .................................................................................................... 110
Client Close Connection .................................................................................................... 112
Client Keep Connection Open .......................................................................................... 113
Dropped Disconnections................................................................................................... 114
Connect TCP Server ........................................................................................................... 115

Connections TIME_WAIT.................................................................................................... 116


WebSocket Redirections.................................................................................................... 117
Connect Secure Server ...................................................................................................... 118
Certificates OpenSSL.......................................................................................................... 119
Certificates SChannel......................................................................................................... 120
SChannel Get Connection Info ......................................................................................... 122
Client Send Text Message ................................................................................................. 123
Client Send Binary Message.............................................................................................. 124
Client Send Text and Binary Message ............................................................................. 125
Receive Text Messages ...................................................................................................... 126
Receive Binary Messages .................................................................................................. 127
Client Authentication ......................................................................................................... 128
Client Exceptions ................................................................................................................ 130
Client WebSocket HandShake .......................................................................................... 131
Client Register Protocol ..................................................................................................... 132
Client Proxies ...................................................................................................................... 133
TsgcWebSocketServer ....................................................................................................... 134
Server Start ......................................................................................................................... 140
Server Bindings................................................................................................................... 141

iv
SGCWEBSOCKETS

Server Startup Shutdown .................................................................................................. 142


Server Keep Active ............................................................................................................. 143
Server SSL............................................................................................................................ 144
Server Keep Connections Alive......................................................................................... 146
Server Plain TCP ................................................................................................................. 147
Server Close Connection ................................................................................................... 148
Server Authentication........................................................................................................ 149
Server Send Text Message ................................................................................................ 150
Server Send Binary Message ............................................................................................ 151
Server Receive Text Message............................................................................................ 152
Server Receive Binary Message........................................................................................ 153
Server Read Headers from Client..................................................................................... 154

TsgcWebSocketHTTPServer .............................................................................................. 155


HTTP Server Requests ....................................................................................................... 159
HTTP Dispatch Files............................................................................................................ 160
HTTP/2 Server ..................................................................................................................... 161
HTTP/2 Server Push ........................................................................................................... 162
HTTP/2 Alternate Service................................................................................................... 164
HTTP 404 Error without Response Body ......................................................................... 165
HTTP Server Sessions ........................................................................................................ 166
TsgcWebSocketServer_HTTPAPI.htm............................................................................... 168
HTTPAPI Server SSL............................................................................................................ 172
Self-Signed Certificates...................................................................................................... 173
HTTPAPI Disable HTTP/2 ................................................................................................... 174
HTTPAPI Custom Headers................................................................................................. 175
HTTPAPI Send Text Response........................................................................................... 176
HTTPAPI Send File Response ............................................................................................ 177
HTTPAPI OnDisconnect not fired ..................................................................................... 178
TsgcWebSocketClient_WinHTTP ....................................................................................... 179
TsgcWebSocketLoadBalancerServer................................................................................ 181
TsgcWebSocketProxyServer.............................................................................................. 182

v
SGCWEBSOCKETS

TsgcIWWebSocketClient .................................................................................................... 183


TsgcWSConnection.htm .................................................................................................... 185
Protocols ............................................................................................................................. 187
Protocols Javascript............................................................................................................ 189
Protocol MQTT.................................................................................................................... 192
TsgcWSPClient_MQTT ........................................................................................................ 194
Client MQTT Connect ......................................................................................................... 200
Connect Mosquitto MQTT Servers ................................................................................... 201
Client MQTT Sessions ........................................................................................................ 202
Client MQTT Version .......................................................................................................... 203
MQTT Publish Subscribe ................................................................................................... 204
MQTT Topics ....................................................................................................................... 205

MQTT Subscribe ................................................................................................................. 206


MQTT Publish Message ..................................................................................................... 207
MQTT Receive Messages ................................................................................................... 208
MQTT Publish and Wait Response ................................................................................... 209
MQTT Clear Retained Messages....................................................................................... 210
Protocol AMQP ................................................................................................................... 211
TsgcWSPClient_AMQP........................................................................................................ 212
Client AMQP Connect ........................................................................................................ 215
Client AMQP Disconnect.................................................................................................... 216
AMQP Channels.................................................................................................................. 217
AMQP Exchanges ............................................................................................................... 219
AMQP Queues .................................................................................................................... 221
AMQP Publish Messages ................................................................................................... 224
AMQP Consume Messages ............................................................................................... 225
AMQP Get Messages.......................................................................................................... 227
AMQP QoS........................................................................................................................... 228
AMQP Transactions............................................................................................................ 229
Protocol STOMP ................................................................................................................. 231
TsgcWSPClient_STOMP...................................................................................................... 232

vi
SGCWEBSOCKETS

TsgcWSPClient_STOMP_RabbitMQ................................................................................... 234
TsgcWSPClient_STOMP_ActiveMQ ................................................................................... 236
Protocol AppRTC ................................................................................................................ 239
TsgcWSPServer_AppRTC.................................................................................................... 240
Protocol WebRTC ............................................................................................................... 241
TsgcWSPServer_WebRTC................................................................................................... 242
Protocol WebRTC Javascript.............................................................................................. 243
Protocol WAMP................................................................................................................... 244
TsgcWSPServer_WAMP...................................................................................................... 245
TsgcWSPClient_WAMP ....................................................................................................... 247
Protocol WAMP Javascript ................................................................................................. 249
Subscribers ......................................................................................................................... 252

Publishers............................................................................................................................ 253
Simple RPC .......................................................................................................................... 254
RPC Progress Results ......................................................................................................... 255
Protocol WAMP2 ................................................................................................................ 257
TsgcWSPClient_WAMP2 ..................................................................................................... 258
Protocol Default ................................................................................................................. 263
TsgcWSPServer_sgc............................................................................................................ 265
TsgcWSPClient_sgc ............................................................................................................. 267
TsgcIWWSPClient_sgc ........................................................................................................ 269
Protocol Default Javascript................................................................................................ 270
Protocol Dataset................................................................................................................. 274
TsgcWSPServer_Dataset .................................................................................................... 275
TsgcWSPClient_Dataset ..................................................................................................... 277
TsgcIWWSPClient_Dataset................................................................................................. 279
Protocol Dataset Javascript ............................................................................................... 280
Protocol Dataset Replicate Table ..................................................................................... 283
Protocol Dataset Notify Updates...................................................................................... 284
Protocol Files ...................................................................................................................... 285
TsgcWSPServer_Files.......................................................................................................... 286

vii
SGCWEBSOCKETS

TsgcWSPClient_Files........................................................................................................... 288
TsgcWSMessageFile ........................................................................................................... 290
How Send Files To Server.................................................................................................. 291
How Send Files To Clients ................................................................................................. 292
How Send Big Files ............................................................................................................. 293
Protocol Presence .............................................................................................................. 294
TsgcWSPServer_Presence ................................................................................................. 295
TsgcWSPresenceMessage ................................................................................................. 298
TsgcWSPClient_Presence................................................................................................... 299
Protocol Presence Javascript ............................................................................................ 302
APIs ...................................................................................................................................... 305
API_Binance.htm ................................................................................................................ 307

Binance Connect WebSocket API ..................................................................................... 312


Binance Subscribe WebSocket Channel .......................................................................... 313
Binance Get Market Data .................................................................................................. 314
Binance Private REST API................................................................................................... 315
Binance Trade Spot............................................................................................................ 316
Binance Private Requests Time ........................................................................................ 318
API_Binance_Futures.htm ................................................................................................. 319
API Binance Futures Trade................................................................................................ 324
API SocketIO........................................................................................................................ 325
API Coinbase Pro ................................................................................................................ 327
Coinbase Pro Connect WebSocket API ............................................................................ 332
Coinbase Pro Subscribe WebSocket Channel................................................................. 333
Coinbase Pro Get Market Data......................................................................................... 334
Coinbase Pro Private REST API ......................................................................................... 335
Coinbase Pro Private Requests Time............................................................................... 336
Coinbase Pro Place Orders ............................................................................................... 337
Coinbase Pro SandBox Account ....................................................................................... 338
API SignalRCore .................................................................................................................. 339
API SignalR .......................................................................................................................... 344

viii
SGCWEBSOCKETS

API Kraken........................................................................................................................... 346


API Kraken WebSockets Public ......................................................................................... 348
API Kraken WebSockets Private........................................................................................ 354
API Kraken REST Public...................................................................................................... 357
API Kraken REST Private .................................................................................................... 359
API Kraken Futures............................................................................................................. 362
API Kraken Futures WebSockets Public........................................................................... 363
API Kraken Futures WebSockets Private ......................................................................... 369
API Kraken Futures REST Public ....................................................................................... 375
API Kraken Futures REST Private ...................................................................................... 377
API FTX ................................................................................................................................. 382
FTX Connect WebSocket API ............................................................................................. 390

FTX Subscribe WebSocket Channel.................................................................................. 391


FTX Get market Data.......................................................................................................... 392
FTX Private REST API .......................................................................................................... 393
FTX Place Orders ................................................................................................................ 394
API Pusher........................................................................................................................... 395
API Bittrex............................................................................................................................ 401
API Bitmex........................................................................................................................... 404
Bitmex Connect WebSocket API ....................................................................................... 407
Bitmex Subscribe WebSocket Channel............................................................................ 408
How Place Bitmex Order ................................................................................................... 409
API Bitfinex.......................................................................................................................... 411
API Discord.......................................................................................................................... 415
API Huobi............................................................................................................................. 418
API Cex................................................................................................................................. 421
API_FXCM.htm .................................................................................................................... 428
API 3Commas ..................................................................................................................... 430
API Blockchain .................................................................................................................... 433
API Telegram....................................................................................................................... 435
Send Telegram Message With Inline Buttons ................................................................. 444

ix
SGCWEBSOCKETS

Send Telegram Message With Buttons............................................................................ 445


Send Telegram Message Bold .......................................................................................... 446
Telegram Chat not found as Bot ...................................................................................... 447
Telegram Get SuperGroup Members .............................................................................. 448
Add Telegram Proxy........................................................................................................... 449
Register Telegram User ..................................................................................................... 450
RCON ................................................................................................................................... 451
CryptoHopper..................................................................................................................... 452
RTCMultiConnection .......................................................................................................... 457
Extensions ........................................................................................................................... 459
PerMessage-Deflate........................................................................................................... 460
Deflate-Frame..................................................................................................................... 461

IoT ........................................................................................................................................ 462


IoT_Amazon_MQTT_Client.htm ........................................................................................ 463
IoT Azure MQTT Client ....................................................................................................... 470
HTTP..................................................................................................................................... 474
HTTP2 .................................................................................................................................. 475
TsgcHTTP2Client................................................................................................................. 476
Request HTTP/2 Method ................................................................................................... 481
HTTP/2 Server Push ........................................................................................................... 482
HTTP/2 Download File ....................................................................................................... 483
HTTP/2 Partial Responses ................................................................................................. 484
HTTP/2 Headers ................................................................................................................. 485
Client Close Connection .................................................................................................... 486
Client Keep Connection Active.......................................................................................... 487
HTTP/2 Reason Disconnection ......................................................................................... 488
Client Pending Requests.................................................................................................... 489
Client Authentication ......................................................................................................... 490
HTTP/2 and OAuth2 ........................................................................................................... 491
TsgcHTTP2ConnectionClient............................................................................................. 492
TsgcHTTP2RequestProperty ............................................................................................. 493

x
SGCWEBSOCKETS

TsgcHTTP2ResponseProperty........................................................................................... 494
Apple Push Notifications ................................................................................................... 495
Register your APP with APNs ............................................................................................ 496
Generate a Remote Notification APNs ............................................................................ 497
Sending Notification Requests to APNs........................................................................... 498
Token-Based Connection to APNs ................................................................................... 499
Certificate-Based Connection to APNs ............................................................................ 500
HTTP1 .................................................................................................................................. 502
OAuth2 ................................................................................................................................ 504
TsgcHTTP_OAuth2_Client .................................................................................................. 505
TsgcHTTP_OAuth2_Server ................................................................................................. 511
OAuth2 Server Example .................................................................................................... 514

OAuth2 Customize Sign-In HTML ..................................................................................... 518


OAuth2 Server Endpoints.................................................................................................. 519
OAuth2 Register Apps ....................................................................................................... 520
OAuth2 Recover Access Tokens ....................................................................................... 521
OAuth2 Server Authentication.......................................................................................... 522
OAuth2 None Authenticate URLs..................................................................................... 523
JWT ....................................................................................................................................... 524
TsgcHTTP_JWT_Client ......................................................................................................... 526
TsgcHTTP_JWT_Server........................................................................................................ 529
Amazon SQS ....................................................................................................................... 531
Google OAuth2 Keys .......................................................................................................... 536
Google Service Accounts ................................................................................................... 542
Google Cloud Pub/Sub ...................................................................................................... 546
Google Calendar................................................................................................................. 555
Google Calendar Sync Calendars ..................................................................................... 561
Google Calendar Sync Events ........................................................................................... 562
Google Calendar RefreshToken........................................................................................ 563
TsgcUDPClient .................................................................................................................... 564
TsgcUDPServer ................................................................................................................... 566

xi
SGCWEBSOCKETS

STUN .................................................................................................................................... 567


TsgcSTUNClient .................................................................................................................. 568
STUN Client UDP Retransmissions................................................................................... 571
STUN Client Long Term Credentials................................................................................. 572
STUN Client Attributes....................................................................................................... 573
TsgcSTUNServer ................................................................................................................. 574
STUN Server Long Term Credentials ............................................................................... 576
STUN Server Alternate Server........................................................................................... 577
TURN.................................................................................................................................... 578
TsgcTURNClient .................................................................................................................. 579
TURN Client Allocate IP Address....................................................................................... 583
TURN Client Create Permissions ...................................................................................... 584

TURN Client Send Indication............................................................................................. 585


TURN Client Channels........................................................................................................ 586
TsgcTURNServer ................................................................................................................. 587
TURN Server Long Term Credentials ............................................................................... 590
TURN Server Allocations.................................................................................................... 591
Datasnap ............................................................................................................................. 592
TsgcWSHTTPWebBrokerBridgeServer ............................................................................. 593
TsgcWSHTTP2WebBrokerBridgeServer........................................................................... 594
TsgcWSServer_HTTPAPI_WebBrokerBridge .................................................................... 595

Demos ................................................................................................................ 596

Server Chat.......................................................................................................................... 596


Client Chat........................................................................................................................... 598
Client.................................................................................................................................... 599
Client MQTT ........................................................................................................................ 600
Client SocketIO ................................................................................................................... 602
Server Monitor.................................................................................................................... 603
Server Snapshots ............................................................................................................... 606
Client Snapshots................................................................................................................. 607

xii
SGCWEBSOCKETS

Upload File .......................................................................................................................... 608


Server Authentication........................................................................................................ 610
KendoUI_Grid...................................................................................................................... 611
ServerSentEvents ............................................................................................................... 613
Server WebRTC ................................................................................................................... 614
Server AppRTC.................................................................................................................... 615
Telegram Client .................................................................................................................. 617

Third-parties...................................................................................................... 619

Coturn.................................................................................................................................. 619

Reference........................................................................................................... 621

WebSockets......................................................................................................................... 621
HTTP/2 ................................................................................................................................. 622
JSON ..................................................................................................................................... 623
JSON-RPC 2.0....................................................................................................................... 624
WAMP .................................................................................................................................. 625
WebRTC ............................................................................................................................... 626
MQTT ................................................................................................................................... 627
Server-Sent Events ............................................................................................................. 628
OAuth2 ................................................................................................................................ 629
JWT ....................................................................................................................................... 630
STUN .................................................................................................................................... 631
AMQP................................................................................................................................... 632
TURN.................................................................................................................................... 633

License ............................................................................................................... 634

License................................................................................................................................. 634

Index................................................................................................................... 636

PDF-Back-Cover ................................................................................................. 641

xiii
INTRODUCTION.HTM

Introduction
WebSockets represent a long-awaited evolution in client/server web technology. They allow a long-held single TCP
socket connection to be established between the client and server which allows for bi-directional, full duplex, mes­
sages to be instantly distributed with little overhead resulting in a very low latency connection.
 
Both the WebSocket API and the well as native WebSocket support in browsers such as Google Chrome, Firefox,
Opera and a prototype Silverlight to JavaScript bridge implementation for Internet Explorer, there are now Web­
Socket library implementations in Objective-C, .NET, Ruby, Java, node.js, ActionScript and many other languages.
 
The Internet wasn’t built to be all that dynamic. It was conceived to be a collection of HyperText Markup Language
(HTML) pages linking to one another to form a conceptual web of information. Over time the static resources in­
creased in number and richer items, such as images, began to be part of the web fabric. Server technologies ad­
vanced allowing for dynamic server pages - pages whose content was generated based on a query.
 
Soon the requirement to have more dynamic web pages lead to the availability of Dynamic HyperText Markup Lan­
guage (DHTML) all thanks to JavaScript (let’s pretend VBScript never existed). Over the following years, we saw
cross frame communication in an attempt to avoid page reloads followed by HTTP Polling within frames. Things
started to get interesting with the introduction of LiveConnect, then the forever frame technique, and finally, thanks
to Microsoft, we ended up with the XMLHttpRequest object and therefore Asynchronous JavaScript and XML
(AJAX). In turn, AJAX made XHR Long-Polling and XHR Streaming possible. But none of these solutions offered a
truly standardised cross-browser solution to real-time bi-directional communication between a server and a client.
 
Finally, WebSockets represent a standard for bi-directional real-time communication between servers and clients.
Firstly in web browsers, but ultimately between any server and any client. The standards first approach means that
as developers we can finally create functionality that works consistently across multiple platforms. Connection limi­
tations are no longer a problem since WebSockets represent a single TCP socket connection. Cross-domain com­
munication has been considered from day one and is dealt with within the connection handshake. This means that
services such as Pusher can easily use them when offering a massively scalable real-time platform that can be
used by any website, web, desktop or mobile application.
 
WebSockets don’t make AJAX obsolete but they do supersede Comet (HTTP Long-polling/HTTP Streaming) as the
solution of choice for true real-time functionality. AJAX should still be used for making short-lived web service calls,
and if we eventually see a good uptake in CORS supporting web services, it will get even more useful. WebSockets
should now be the go-to standard for real-time functionality since they offer low latency bi-directional communica­
tion over a single connection. Even if a web browser doesn’t natively support the WebSocket object there are poly­
fill fallback options which all but guarantee any web browser can actually establish a WebSocket connection.
 
sgcWebSockets is a complete package providing access to WebSockets protocol, allowing to create WebSockets
Servers, Intraweb Clients or WebSocket Clients in VCL, Firemonkey, Linux and FreePascal applications.
 
• Fully functional multithreaded WebSocket server according to RFC 6455.
• Supports Firemonkey (Windows and MacOS).
• Supports NEXTGEN Compiler (IOS and Android Support).
• Supports LINUX Compiler.
• Supports Lazarus / FreePascal.
• Supports CBuilder.
• Supports Chrome, Firefox, Safari, Opera and Internet Explorer (including iPhone, iPad and iPod)
• Supports Microsoft HTTP Server API and IOCP for high-performance Windows Servers. HTTP/2 protocol
is supported.
• Multiple Threads Support. Indy Servers support IOCP or default Indy one thread per connection model.
• Supports Message Compression using PerMessage_Deflate extension RFC 7692.
• Supports Text and Binary Messages.
• Supports Server and Client Authentication. OAuth2 is fully supported.
• Server component providing WebSocket and HTTP/2 connections through the same port.
• Proxy Server component allowing to Web Browsers to connect to any TCP server.
• WebBroker Server which supports DataSnap, HTTP/2 and WebSocket connections using the same port.
• Load Balancing Server.
• Client WebSocket based on WinHTTP API.
• Client WebSocket supports connections through Socket.IO Servers.
• HTTP/2 protocol is fully supported (client and Server components).

14
INTRODUCTION.HTM

• STUN and TURN protocols are fully supported (client and Server components).
• Supports Server-Sent Events (Push Notifications) over HTTP Protocol.
• WatchDog and HeartBeat built-in support.
• Client WebSocket supports connections through HTTP Proxy Servers and SOCKS Proxy Servers.
• Events Available: OnConnect, OnDisconnect, OnMessage, OnError, OnHandshake
• Built-in sub-protocols: JSON-RPC 2.0, Dataset, Presence, WebRTC, MQTT (3.1.1 and 5.0), STOMP,
AMQP and WAMP (1.0 and 2.0)
• Client Built-in API: Blockchain, Bitfinex, Pusher, SignalR Core, Huobi, CEX, Bitmex and Bittrex.
• Support for JSON parsers: Delphi JSON and XSuperObject.
• Built-in Javascript libraries to support browser clients.
• Easy to setup
• Javascript Events for full control
• Async Events using Ajax
• SSL/TLS Support for Server / Client Components (OpenSSL libraries required). OpenSSL 1.1.1 and 3.0.0 li­
braries are supported. Client supports SChannel for Windows.
 
 
 
 
Find below a list of the components included in sgcWebSockets Library.
 
1 sgcWebSockets
◦ TsgcWebSocketClient: WebSocket Client based on Indy Library.
◦ TsgcWebSocketServer: WebSocket Server based on Indy Library
◦ TsgcWebSocketHTTPServer: WebSocket + HTTP Server based on Indy Library.
◦ TsgcWebSocketServer_HTTPAPI: Fast Performance WebSocket + HTTP Server based on 
HTTP.SYS Microsoft HTTP API.
◦ TsgcWebSocketClient_WinHTTP: WebSocket Client based on WinHTTP Library.

2 sgcWebSocket APIs
◦ TsgcWSAPI_Binance: Binance Spot Client, supports WebSocket + REST APIs.
◦ TsgcWSAPI_Binance_Futures: Binance Futures Client, supports WebSocket + REST APIs.
◦ TsgcWSAPI_SocketIO: Socket.IO Client.
◦ TsgcWSAPI_Coinbase:Coinbase Pro Client, supports WebSocket + REST APIs.
◦ TsgcWSAPI_Bitmex: Bitmex Client, supports WebSocket + REST APIs.
◦ TsgcWSAPI_SignalR: SignalR WebSocket Client.
◦ TsgcWSAPI_SignalRCore: SignalRCore WebSocket Client.
◦ TsgcWSAPI_Pusher: Pusher WebSocket Client.
◦ TsgcWSAPI_Kraken: Kraken Client API, supports WebSocket and REST Api.
◦ TsgcWSAPI_Kraken_Futures: Kraken Futures Client API, supports WebSocket and REST Api.
◦ TsgcWSAPI_Bitstamp: Bitstamp WebSocket Client.
◦ TsgcWSAPI_Bittrex: Bittrex WebSocket Client.
◦ TsgcWSAPI_Cex: Cex WebSocket Client.
◦ TsgcWSAPI_FTX: FTX WebSocket Client.
◦ TsgcWSAPI_FXCM: FXCM WebSocket Client.
◦ TsgcWSAPI_Huobi: Huobi WebSocket Client.
◦ TsgcWSAPI_ThreeCommas: ThreeCommas Client API.
◦ TsgcWSAPI_Bitfinex: Bitfinex WebSocket API.
◦ TsgcWSAPI_Discord: Discord WebSocket Client.

15
INTRODUCTION.HTM

◦ TsgcWSAPI_BlockChain: BlockChain WebSocket Client.

3 sgcWebSocket Libs
◦ TsgcTDLib_Telegram: Telegram API Client.
◦ TsgcHTTP_Cryptohopper: Cryptohopper Client API.
◦ TsgcLib_RCON: RCON Client.

4 sgcWebSocket Protocols
◦ TsgcWSPClient_MQTT: MQTT (3.1.1 and 5.0) Client. Supports WebSocket and Plain TCP Connec­
tions.
◦ TsgcWSPClient_AMQP: AMQP 0.9.1 Client. Supports RabbitMQ Brokers.
◦ TsgcWSPClient_STOMP: STOMP Client, supports WebSocket and Plain TCP Connections.
▪ TsgcWSPClient_STOMP_ActiveMQ: STOMP Client for ActiveMQ Broker.
▪ TsgcWSPClient_STOMP_RabbitMQ: STOMP Client for RabbitMQ Broker.
◦ TsgcWSPClient_WAMP: WAMP 1.0 Client Protocol.
◦ TsgcWSPServer_WAMP: WAMP 1.0 Server Protocol.
◦ TsgcWSPClient_WAMP2: WAMP 2.0 Client Protocol.
◦ TsgcWSPServer_AppRTC: WebRTC Server based on AppRTC Google Project.
◦ TsgcWSPServer_WebRTC: WebRTC Server Protocol.
◦ TsgcWSPClient_sgc: WebSocket Client SGC Protocol based on JSON RPC.
◦ TsgcWSPServer_sgc: WebSocket Server SGC Protocol based on JSON RPC.
◦ TsgcWSPClient_Files: WebSocket File Transfer Client Protocol.
◦ TsgcWSPServer_Files: WebSocket File Transfer Server Protocol.
◦ TsgcWSPClient_Dataset: WebSocket Client Dataset Synchronization Protocol.
◦ TsgcWSPServer_Dataset: WebSocket Server Dataset Synchronization Protocol.
◦ TsgcWSPClient_Presence: WebSocket Client Presence Protocol.
◦ TsgcWSPServer_Presence: WebSocket Server Presence Protocol.

5 sgcWebSockets HTTP
◦ TsgcHTTP1Client:HTTP 1.0 Client based on Indy TIdHTTP.
◦ TsgcHTTP2Client: HTTP 2.0 Client.
◦ TsgcHTTP_JWT_Client: JWT (JSON WEB TOKEN) Client.
◦ TsgcHTTP_JWT_Server: JWT (JSON WEB TOKEN) Server.
◦ TsgcHTTP_OAuth2_Client: OAuth 2.0 Client.
◦ TsgcHTTP_OAuth2_Server: OAuth 2.0 Server.
◦ TsgcHTTPAWS_SQS_Client: Amazon AWS SQS Client.
◦ TsgcHTTPGoogleCloud_PubSub_Client: Google Cloud Pub/Sub Client.
◦ TsgcHTTPGoogleCloud_Calendar_Client: Google Calendar Client.

6 sgcWebSockets IoT
◦ TsgcIoTAmazon_MQTT_Client: Amazon MQTT IoT Core Client.
◦ TsgcIoTAzure_MQTT_Client: Azure IoT MQTT Client.

7 sgcWebSockets P2P

16
INTRODUCTION.HTM

◦ TsgcUDPCLient: UDP Client.


◦ TsgcUDPServer: UDP Server.
◦ TsgcSTUNClient: STUN Client.
◦ TsgcSTUNServer: STUN Server.
◦ TsgcTURNClient: STUN / TURN Client.
◦ TsgcTURNServer: STUN / TURN Server.

8 sgcWebSockets DataSnap
◦ TsgcWSHTTPWebBrokerBridgeServer: DataSnap Server Replacement with HTTP + WebSockets
Support.
◦ TsgcWSHTTP2WebBrokerBridgeServer: DataSnap Server Replacement with HTTP + HTTP/2 +
WebSockets Support.
◦ TsgcWSServer_HTTPAPI_WebBrokerBridge: DataSnap Server Replacement based on HTTP.SYS
Microsoft Server.
 
 

17
OVERVIEW

Versions Support
Delphi supported IDE
• Delphi 7 (* only supported if upgraded to Indy 10, Intraweb is not supported)
• Delphi 2007
• Delphi 2009
• Delphi 2010
• Delphi XE
• Delphi XE2
• Delphi XE3
• Delphi XE4
• Delphi XE5
• Delphi XE6
• Delphi XE7
• Delphi XE8
• Delphi 10 Seattle
• Delphi 10.1 Berlin
• Delphi 10.2 Tokyo
• Delphi 10.3 Rio
• Delphi 10.4 Sydney
• Delphi 11 Alexandria
 

CBuilder supported IDE


• CBuilder 2010
• CBuilder XE
• CBuilder XE2
• CBuilder XE3
• CBuilder XE4
• CBuilder XE5
• CBuilder XE6
• CBuilder XE7
• CBuilder XE8
• CBuilder 10 Seattle
• CBuilder 10.1 Berlin
• CBuilder 10.2 Tokyo
• CBuilder 10.3 Rio
• CBuilder 10.4 Sydney
• CBuilder 11 Alexandria
 
 

FreePascal supported IDE


• Lazarus
 

Trial Version
Compiled *.dcu files provided with free version are using default Indy and Intraweb version. If you have upgraded
any of these packets, probably it won't work or you need to buy full source code version.
 

18
OVERVIEW

Indy Package
Some components use Indy as TCP/IP library (like TsgcWebSocketClient or TsgcWebSocketServer), this means
that Indy is needed in order to install sgcWebSockets Package. By default, sgcWebSockets uses Indy library built-
in with Rad Studio, but we provide a custom indy version which has more features than Indy: support for OpenSSL
API 1.1, ALPN protocol...
 

19
OVERVIEW

Installation
Delphi / CBuilder / Lazarus
 
1. Unzip the files included into a directory {$DIR}
 
2. From Delphi\CBuilder:
 
Add the directory where the files are unzipped {$DIR} to the Delphi\CBuilder library path under Tools, Envi­
ronment options, Directories
 
All Delphi\CBuilder Versions
 
Add the directory {$DIR}\source to the library path
 
For specific Delphi version
 
Delphi 7          : Add the directory {$DIR}\libD7 to the library path
Delphi 2007     : Add the directory {$DIR}\libD2007 to the library path
Delphi 2009     : Add the directory {$DIR}\libD2009 to the library path
Delphi 2010     : Add the directory {$DIR}\libD2010 to the library path
Delphi XE        : Add the directory {$DIR}\libDXE   to the library path
Delphi XE2      : Add the directory {$DIR}\libDXE2\$(Platform)  to the library path
Delphi XE3      : Add the directory {$DIR}\libDXE3\$(Platform)  to the library path  
Delphi XE4      : Add the directory {$DIR}\libDXE4\$(Platform)  to the library path 
Delphi XE5      : Add the directory {$DIR}\libDXE5\$(Platform)  to the library path  
Delphi XE6      : Add the directory {$DIR}\libDXE6\$(Platform)  to the library path  
Delphi XE7      : Add the directory {$DIR}\libDXE7\$(Platform)  to the library path  
Delphi XE8      : Add the directory {$DIR}\libDXE8\$(Platform)  to the library path  
Delphi 10        : Add the directory {$DIR}\libD10\$(Platform)  to the library path  
Delphi 10.1     : Add the directory {$DIR}\libD10_1\$(Platform)  to the library path 
Delphi 10.2    : Add the directory {$DIR}\libD10_2\$(Platform)  to the library path 
Delphi 10.3    : Add the directory {$DIR}\libD10_3\$(Platform)  to the library path 
Delphi 10.4    : Add the directory {$DIR}\libD10_4\$(Platform)  to the library path 
Delphi 11       : Add the directory {$DIR}\libD11\$(Platform)  to the library path 
 
 
 
 
For specific CBuilder version
 
C++ Builder 2010     : Add the directory {$DIR}\libD2010 to the library path
C++ Builder XE        : Add the directory {$DIR}\libDXE   to the library path
C++ Builder XE2      : Add the directory {$DIR}\libDXE2\$(Platform)  to the library path
C++ Builder XE3      : Add the directory {$DIR}\libDXE3\$(Platform)  to the library path  
C++ Builder XE4      : Add the directory {$DIR}\libDXE4\$(Platform)  to the library path 
C++ Builder XE5      : Add the directory {$DIR}\libDXE5\$(Platform)  to the library path  
C++ Builder XE6      : Add the directory {$DIR}\libDXE6\$(Platform)  to the library path  
C++ Builder XE7      : Add the directory {$DIR}\libDXE7\$(Platform)  to the library path  
C++ Builder XE8      : Add the directory {$DIR}\libDXE8\$(Platform)  to the library path  
C++ Builder 10        : Add the directory {$DIR}\libD10\$(Platform)  to the library path  
C++ Builder 10.1     : Add the directory {$DIR}\libD10_1\$(Platform)  to the library path  
C++ Builder 10.2     : Add the directory {$DIR}\libD10_2\$(Platform)  to the library path  
C++ Builder 10.3     : Add the directory {$DIR}\libD10_3\$(Platform)  to the library path  
C++ Builder 10.4     : Add the directory {$DIR}\libD10_4\$(Platform)  to the library path  
C++ Builder 11        : Add the directory {$DIR}\libD11\$(Platform)  to the library path  
 
 
For all CBuilder versions, Add dcp\$(Platform) to the library path (contains .bpi files)

20
OVERVIEW

 
 
 
 
3. From Delphi
 
Choose
File, Open and browse for the correct Packages\sgcWebSockets.groupproj (First compile
sgcWebSocketsX.dpk and then install dclsgcWebSocketsX.dpk)
   
packages files for Delphi
 
sgcWebSocketsD7.groupproj          : Delphi 7
sgcWebSocketsD2007.groupproj     : Delphi 2007
sgcWebSocketsD2009.groupproj     : Delphi 2009
sgcWebSocketsD2010.groupproj     : Delphi 2010
sgcWebSocketsDXE.groupproj        : Delphi XE
sgcWebSocketsDXE2.groupproj       : Delphi XE2
sgcWebSocketsDXE3.groupproj       : Delphi XE3
sgcWebSocketsDXE4.groupproj       : Delphi XE4
sgcWebSocketsDXE5.groupproj       : Delphi XE5
sgcWebSocketsDXE6.groupproj       : Delphi XE6
sgcWebSocketsDXE7.groupproj       : Delphi XE7
sgcWebSocketsDXE8.groupproj       : Delphi XE8
sgcWebSocketsD10.groupproj         : Delphi 10
sgcWebSocketsD10_1.groupproj      : Delphi 10.1
sgcWebSocketsD10_2.groupproj      : Delphi 10.2
sgcWebSocketsD10_3.groupproj      : Delphi 10.3
sgcWebSocketsD10_4.groupproj      : Delphi 10.4
sgcWebSocketsD11.groupproj          : Delphi 11
 
 
 
4. From CBuilder
 
Choose
File, Open and browse for the correct Packages\sgcWebSockets.groupproj (First compile
sgcWebSocketsX.dpk and then install dclsgcWebSocketsX.dpk)
   
packages files for CBuilder
 
sgcWebSocketsC2010.groupproj     : C++ Builder 2010
sgcWebSocketsCXE.groupproj        : C++ Builder XE
sgcWebSocketsCXE2.groupproj      : C++ Builder XE2
sgcWebSocketsCXE3.groupproj      : C++ Builder XE3
sgcWebSocketsCXE4.groupproj      : C++ Builder XE4
sgcWebSocketsCXE5.groupproj      : C++ Builder XE5
sgcWebSocketsCXE6.groupproj      : C++ Builder XE6
sgcWebSocketsCXE7.groupproj      : C++ Builder XE7
sgcWebSocketsCXE8.groupproj      : C++ Builder XE8
sgcWebSocketsC10.groupproj        : C++ Builder 10
sgcWebSocketsC10_1.groupproj     : C++ Builder 10.1
sgcWebSocketsC10_2.groupproj     : C++ Builder 10.2
sgcWebSocketsC10_3.groupproj     : C++ Builder 10.3
sgcWebSocketsC10_4.groupproj     : C++ Builder 10.4
sgcWebSocketsC11.groupproj         : C++ Builder 11
 
 
 
 
5. From Lazarus
 
Choose : File, Open and browse Packages\sgcWebSocketsLazarus.lpk (First compile and then install)
   

21
OVERVIEW

Compiled files are located on Lazarus Directory, inside this, there is a Indy directory with latest Indy source
version.
 
Tested with Lazarus 2.0.6 and Indy 10.5.9.4930
 
 
6. Demos
  
All demos are available in subdirectory Demos. Just open the project and run it. Intraweb demos may need
to modify some units due to different Intraweb Versions.
 
 
 
 
 
 

22
INSTALL

Install Package
Follow next steps to install sgcWebSockets package, screenshots use Delphi 10.3 version.
 
1. Open sgcWebSocketsD10_3 group project.
 

 
2. Now we must compile first runtime packages (name starts with sgcWebSockets). There is one package for
every target platform and this depends of Delphi version, so select target platform one by one and build every
package.
 
3. Select win64 as Target platform and build package.
 

23
INSTALL

 
4. Select Android as Target Platform and build package.
 

 
5. Select iOS Device 32 as Target Platform and build package.
 

24
INSTALL

 
6. Select iOS Device 64 as Target Platform and build package.
 

 
7. Select iOS Device Simulator as Target Platform and build package.
 

25
INSTALL

 
8. Select MacOS 32 as Target Platform and build package.
 

 
9. Select Win32 as Target Platform and build package.
 

26
INSTALL

 
10. Once all runtime packages are compiled, select design time package (name starts with dcl) and first build and
then install (design time packages only have Win32 as target platform).
 

27
INSTALL

 
11. If installation is successful you will see a message with all components installed.
 

 
 
12. Then, you only must to add the Directory where are the compiled files to your Rad Studio Library Path. You
must add this for every Target Platform (win32, win64, osx64...)
 

28
INSTALL

 
* If you are using the Datasnap servers, these are NOT included in sgcWebSockets package because cannot be
installed, are only runtime components. In this case, you must add to your library path the Source folder too.
 
 

29
INSTALL

Install Errors
Sometimes you may get some errors installing components.
 

Intraweb package not found


sgcWebsockets is compiled using the default Intraweb version provided with Delphi. If you don't have Intraweb in­
stalled, you can modify sgcVer.inc file (located in Source folder).
Search your Delphi version and comment all compiler defines for Intraweb (starts with IW). Example: for Delphi
10.4 comment all compiler defines for Intraweb
 
{$IFDEF VER340} { Delphi  10.4 }
  {$DEFINE D2006}
  {$DEFINE D2007}
  {$DEFINE D2009}
  {$DEFINE D2010}
  {$DEFINE DXE}
  {$DEFINE DXE2}
  {$DEFINE DXE3}  
  {$DEFINE DXE4}
  {$DEFINE DXE5}
  {$DEFINE DXE6}
  {$DEFINE DXE7}
  {$DEFINE DXE8}
  {$DEFINE D10}
  {$DEFINE D10_1}
  {$DEFINE D10_2}
  {$DEFINE D10_3}
  {$DEFINE D10_4}
  {$DEFINE INDY10_1}
  {$DEFINE INDY10_2}
  {$DEFINE INDY10_5_5}
  {$DEFINE INDY10_5_7}
  {$DEFINE INDY10_5_8}
  {$DEFINE INDY10_6}
  {$DEFINE INDY10_6_0_5122}
  {$DEFINE INDY10_6_0_5169}
  {$DEFINE INDY10_6_2_5263}
  {$DEFINE INDY10_6_2_5366}
  {$DEFINE INDY10_6_2_D10_4}
  
  {$IFNDEF BCB}
    {$IFNDEF MACOS}
    {$IFNDEF ANDROID}
      {.$DEFINE IWIX}
      {.$DEFINE IWXI}
      {.$DEFINE IWXIV}  
      {.$DEFINE IWXV}
    {$ENDIF}
    {$ENDIF}
    {$IFNDEF NEXTGEN}
      {$DEFINE SGC_JSON_INTF}
    {$ENDIF}
  {$ENDIF}
{$ENDIF}
 
If Intraweb is installed but it's a different version from the default that comes with Delphi, maybe your Intraweb
package has a different name. Then open sgcWebSockets runtime package and change Intraweb name in project
source.
 

30
INSTALL

 
 

Indy Package not found


 
sgcWebSockets requires Indy to install components in your IDE. Trial installation is compiled against Indy library
provided with Delphi / CBuilder, so if you get a message like this:
 
[DCC Fatal Error] dclsgcWebSocketsDX.dpk(31): E2202 Required package 'IndyCore' not found
 
Most probably you have a newer Indy version, so in order to install trial you must delete this version and install
built-in indy version using Delphi / CBuilder setup.
 
If you have full source code, then you only must check:
 
1. Required Indy packages: IndyCore, IndySystem and IndyProtocols. If you have a newer Indy version, most prob­
ably packages have a different name (including version), so access to menu "Component / Install Packages" and
check which name have Indy packages and change accordingly in the project.
 
2. sgcWebSockets supports several Indy versions, there are compiler defines to allow compile for every Indy ver­
sion. Open sgcVer.inc, located in the source folder, and change accordingly for your Indy version (is gsIdVersion of
IdVers.inc Indy file). Some compiler defines:
 
  {$DEFINE INDY10_1}
  {$DEFINE INDY10_2}
  {$DEFINE INDY10_5_5}
  {$DEFINE INDY10_5_7}
  {$DEFINE INDY10_5_8}
  {$DEFINE INDY10_6}
  {$DEFINE INDY10_6_0_5122}
  {$DEFINE INDY10_6_0_5169}
  {$DEFINE INDY10_6_2_5263}
  {$DEFINE INDY10_6_2_5366}
  {$DEFINE INDY10_6_2_D10_4}
 

31
INSTALL

c00000005 ACCESS_VIOLATION in CBuilder


If you compile a project using CBuidler and you get this error, set the following options in your project:
 
Project > Options > C++ Linker
uncheck "Link with Dynamic RTL"
 
Project > Options > Packages > Runtime Packages
uncheck "Link with runtime packages"
 
 

Unable to find package import: sgcWebSocketsCXXX.bpi in CBuilder Win64


When you compile runtime package for win64, you must compile Release and Debug.
 
 

Ambiguous reference System.ZLib.hpp and IdZLib.hpp CBuilder


sgcWebSockets uses Indy for some components and Indy doesn't make use of ZLib unit, uses its own copy of
ZLib: IdZLib, IdZLibHeaders... the project is linking to ZLib and indy ZLib units, so when compile, compiler doesn't
know which is the correct reference because names are the same. There are 2 solutions:
 
1. Search where is included a link to System.ZLib.hpp and delete or move after IdZLibHeaders.hpp
2. Use the following conditional defines NO_USING_NAMESPACE_SYSTEM_ZLIB or
DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE in your projects options to avoid the use of System.Zlib.hpp
 
 

Checksum changed under Lazarus


This error can be raised while trying to install the components under Lazarus if the profile to build the IDE is not
"Optimized IDE". The trial is compiled with the profile "Optimized IDE".

32
INSTALL

Configure Install
In the source folder, there is a file called sgcVer.inc which includes all compiler defines for all Delphi, CBuilder and
Lazarus IDEs.
 
Here you can customize your configuration for Intraweb, Indy... usually there is no need to do any changes, un­
less you want enable/disable some features.
 
Change carefully the compiler defines and contact us if you require assistance.
 
For every Delphi version, there is a section where you can configure all compiler defines, an example for Delphi
10.4
 
{$IFDEF VER340} { Delphi  10.4 }
  {$DEFINE D2006}
  {$DEFINE D2007}
  {$DEFINE D2009}
  {$DEFINE D2010}
  {$DEFINE DXE}
  {$DEFINE DXE2}
  {$DEFINE DXE3}  
  {$DEFINE DXE4}
  {$DEFINE DXE5}
  {$DEFINE DXE6}
  {$DEFINE DXE7}
  {$DEFINE DXE8}
  {$DEFINE D10}
  {$DEFINE D10_1}
  {$DEFINE D10_2}
  {$DEFINE D10_3}
  {$DEFINE D10_4}
  {$DEFINE INDY10_1}
  {$DEFINE INDY10_2}
  {$DEFINE INDY10_5_5}
  {$DEFINE INDY10_5_7}
  {$DEFINE INDY10_5_8}
  {$DEFINE INDY10_5_9}
  {$DEFINE INDY10_6}
  {$DEFINE INDY10_6_0_5122}
  {$DEFINE INDY10_6_0_5169}
  {$DEFINE INDY10_6_2_5263}
  {$DEFINE INDY10_6_2_5366}
  {$DEFINE INDY10_6_2_D10_4}
  
  {$IFNDEF BCB}
    {$IFNDEF MACOS}
    {$IFNDEF ANDROID}
      {.$DEFINE IWIX}
      {.$DEFINE IWXI}
      {.$DEFINE IWXIV}  
      {.$DEFINE IWXV}
    {$ENDIF}
    {$ENDIF}
    {$IFNDEF NEXTGEN}
      {$DEFINE SGC_JSON_INTF}
    {$ENDIF}
  {$ENDIF}
{$ENDIF}
 

33
INSTALL

Indy
There are some compiler defines for Indy library. This depends on Indy version installed, by default is configured for
Indy package included with Delphi. Indy version is gsIdVersion parameter of IdVers.inc Indy file.
 

Intraweb
If Intraweb is not installed, just comment compiler defines for Intraweb (those who starts with IW...)

34
INSTALL

Install sgcIndy Package


If Indy is already installed, it needs to be uninstalled first.
 
1. Remove the pre-compiled BPL files - dclIndyCoreX.bpl and dclIndyProtocolsX.bpl - from the IDE via the
"Components > Install Packages" dialog.
2. Then delete all of the existing binaries (IndySystemX., IndyCoreX., IndyProtocolsX., dclIndyCoreX., and
dclIndyProtocolsX.*) as well as delete any Indy 10 source files, if present.
3. Be sure to check for files in the IDE's \bin, \lib, and \source folders, \Indy subfolders, and OS system fold­
ers."
 
To install the sgcIndy package, you can either
 
1. Use the command-line FULLD#.BAT script that corresponds to your Delphi version.
2. Open the individual DPK files in the IDE and compile them, in the following order:
1. IndySystemX.dpk (in Lib\System)
2. IndyCoreX.dpk (in Lib\Core)
3. IndyProtocolsX.dpk (in Lib\Protocols)
4. dclIndyCoreX.dpk (in Lib\Core)
5. dclIndyProtocolsX.dpk (in Lib\Protocols)

35
QUICKSTART

QuickStart
WebSockets Components
Creating a new WebSocket Server or WebSocket client is very simple, just create a new instance of the class, con­
figure the Host / Port and set the property Active = true to start the process.
 
QuickStart WebSockets
 

HTTP Components
The HTTP/2 protocol allows to create much faster HTTP Servers / Clients than using HTTP/1 protocol. The HTTP/2
Server is included in the WebSocket server while the HTTP/2 client is a dedicated components which implements
the HTTP/2 protocol.
 
QuickStart HTTP
 
 

Threading Flow
sgcWebSockets components are threaded, which means that connections runs in secondary threads. By de­
fault, the main events are dispatched on the main thread, this is useful when the number of events to dispatch is
low, but for better performance you can configure the components where the events are dispatched in the con­
text of connection thread. Read the following article which explains how configure threading flow:
 
How Configure NotifyEvents
 
 

How Build Applications


Build Applications with sgcWebSockets library is very easy, just follow the next tips which will helps to successfully
build your application.
 
Build
 
 

Fast Performance Server


sgcWebSockets has 2 server implementations: 1 based on Indy server and another based on HTTP.SYS Mi­
crosoft Server. The latest is the recommended for High Performance Servers which requires to handle thousands
of concurrents connections. Check the following article which explains how improve server performance.
 
Fast Performance Server
 
 

Memory Manager
Choose an adequate memory manager can improve the performance of your application, check the following article
which shows a comparison between some memory managers
 
Memory Manager
 

36
QUICKSTART

OpenSSL
When your application requires secure connections, usually openSSL libraries are required to encrypt communi­
cations, follow the next steps to configure successfully your application with openSSL libraries.
 
Configure OpenSSL
 
 

Indy
The Indy library is used as a base in some sgcWebSockets components, sgcWebSockets Enterprise edition in­
cludes a custom indy version which allows to use openSSL 1.1.1 and openSSL 3.0.0, ALPN...
 
Indy
 

Linux (Lazarus)
If you compile a Lazarus project for Linux and you get this message:
 
Semaphore init failed (possibly too many concurrent threads)
 
Just add cthreads unit to your project file.
 

37
QUICKSTART

QuickStart | WebSockets
Let's start with a basic example where we need to create a Server WebSocket and 2 client WebSocket types: Ap­
plication Client and Web Browser Client.
 

WebSocket Server
1. Create a new Window Forms Application
2. Drop a TsgcWebSocketServer onto a Form.
3. On Events Tab, Double click OnMessage Event, and type following code:

procedure OnMessage(Connection: TsgcWSConnection; const Text: string);


begin
  ShowMessage('Message Received From Client: ' + Text);
end;

4. Drop a Button onto the Form, Double Click and type this code:

TsgcWebSocketServer1.Active := True;

WebSocket Client
1. Create a new Window Forms Application
2. Drop a TsgcWebSocketClient onto a Form and configure Host and Port Properties to connect to Server.
3. Drop a TButton in a Form, Double Click and type this code:

TsgcWebSocketClient1.Active := True;

4. Drop a Button onto the Form, Double Click and type this code:

TsgcWebSocketClient1.WriteData('Hello Server From VCL Client');

Web Browser Client


 
1. Create a new HTML file
 
2. Open file with a text editor and copy following code:
 

<html>
<head>
<script type="text/javascript" src="http://host:port/sgcWebSockets.js"></script>
</head>
<body>
<a href="javascript:var socket = new sgcWebSocket('ws://host:port');">Open</a>
<a href="javascript:socket.send('Hello Server From Web Browser');">Send</a>
</body>
</html>

 
  You need to replace host and port in this file for your custom Host and Port!!
 
3. Save File and that's all, you have configured a basic WebSocket Web Browser Client.

38
QUICKSTART

 
 
 

How To Use
 
1. Start Server Application and press button to start WebSocket Server to listen new connections.
 
2. Start Client Application and press button1 to connect to server and press button2 to send a message. On Server
Side, you will see a message with text sent by Client.
 
3. Open then HTML file with your Web Browser (Chrome, Firefox, Safari or Internet Explorer 10+), press Open to
open a connection and press send, to send a message to the server. On Server Side, you will see a message with
a text sent by Web Browser Client.
 
 
 

Linux Compiler
Simple Server example (listening on port 5000).
 

program sgcWebSockets_linux;
 
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
  System.SysUtils, sgcWebSocket;
 
var
  oServer: TsgcWebSocketServer;
 
begin
  try
    oServer := TsgcWebSocketServer.Create(nil);
    oServer.Port := 5000;
    oServer.Active := True;
 
    while oServer.Active do
      Sleep(10);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

 
 
 

Linux (Lazarus)
If you compile a Lazarus project for Linux and you get this message:
 
Semaphore init failed (possibly too many concurrent threads)
 
Just add cthreads unit to your project file.
 

39
QUICKSTART

QuickStart | HTTP
Let's start with a basic example where we need to create a HTTP/2 Server and a HTTP/2 client.
 

HTTP/2 Server
1. Create a new Window Forms Application
2. Drop a TsgcWebSocketHTTPServer onto a Form.
3. On Events Tab, Double click OnCommandGet Event, and type following code:
 

procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;


  AResponseInfo: TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document = '/' then
  begin
    AResponseInfo.ContentText := '<html><head><title>Test Page</title></head><body></body></html>';
    AResponseInfo.ContentType := 'text/html';
    AResponseInfo.ResponseNo := 200;
  end;
end;

4. By default, the server only enables HTTP/1 connections, so enable HTTP/2 options in the property
HTTP2Options.Enabled = true, and then configure the SSL Options. Secure connections require OpenSSL li­
braries.
 

TsgcWebSocketHTTPServer1.Port := t443;
TsgcWebSocketHTTPServer1.SSL := true;
TsgcWebSocketHTTPServer1.SSLOptions.CertFile := 'server cert file';
TsgcWebSocketHTTPServer1.SSLOptions.KeyFile := 'server private key file';
TsgcWebSocketHTTPServer1.SSLOptions.RootCertFile := 'server root cert file';
TsgcWebSocketHTTPServer1.SSLOptions.OpenSSL_Options.APIVersion := oslAPI_1_1;
TsgcWebSocketHTTPServer1.SSLOptions.Port := 443;
TsgcWebSocketHTTPServer1.SSLOptions.Version := tls1_3;

 
5. Drop a Button onto the Form, Double Click and type this code:

TsgcWebSocketHTTPServer1.Active := True;

HTTP/1 Client
1. Create a new Window Forms Application
2. Drop a TButton in a Form, Double Click and type this code:
 

var
  oHTTP1: TsgcHTTP1Client;
begin
  oHTTP1 := TsgcHTTP1Client.Create(nil);
  Try
    ShowMessage(oHTTP1.Get('https://127.0.0.1'));
  Finally
    oHTTP1.Free;
  End;
end;

40
QUICKSTART

HTTP/2 Client
1. Create a new Window Forms Application
2. Drop a TButton in a Form, Double Click and type this code:
 

var
  oHTTP2: TsgcHTTP2Client;
begin
  oHTTP2 := TsgcHTTP2Client.Create(nil);
  Try
    ShowMessage(oHTTP2.Get('https://127.0.0.1'));
  Finally
    oHTTP2.Free;
  End;
end;

41
QUICKSTART

QuickStart | Threading Flow


sgcWebSockets components are threaded, for example, TsgcWebSocketHTTPServer (based on Indy library) cre­
ates one thread for every connection while TsgcWebSocketServer_HTTPAPI (based on Microsoft HTTP.SYS)
runs a pool of threads and the connections are handled by this pool of threads (max of 64 threads) and TsgcWeb­
SocketClient runs his own thread to run asynchronously the responses from WebSocket server.
 
By default, there is a property called NotifyEvents, which has the value neAsynchronous. This means that when a
WebSocket client receives a message, this message is queued and is dispatched on the main thread by OS later.
This runs well for clients that doesn't receive a lot of messages and for easy of use, because doesn't require to syn­
chronize with the main thread when you want for example update a control of your form.
 
But when the server / client must process several messages in short period of time, it's better change this threading
flow to another where the events are dispatched in the context of connection thread. To do this, just set Noti­
fyEvents property to neNoSync, this way, when for example a client receives a message from server, this message
will be dispatched in the context of a secondary thread, so if you need to update a control of your form, first syn­
chronize with the main thread and the update the form control (because form controls are not thread safe). The
same applies if you want access to a shared object, you need to implement your own synchronization methods.
 
 
Threading Flow Easy Mode (NotifyEvents = neAsynchronous) and Low Performance
 
This is the threading flow by default and it's usually used on demo samples. Select this mode if you don't expect to
handle several messages per seconds and you need update Form Controls or access shared objects.
 
NotifyEvents = neAsynchronous
 
 
 
Threading Flow Best Performance (NotifyEvents = neNoSync)
 
Set this threading flow for server components and for clients which needs a high performance because you expect
will require to handle several messages. Using this configuration, the events are dispatched in the context of con­
nection thread, so in order to update a Form control, first synchronize with the main thread.
 
NotifyEvents = neNoSync
 
 
How Synchronize Main Thread
 
You can synchronize with Main Thread calling TThread.Synchronize or TThread.Queue, both methods can be used
and select one or another depends of how you want implement synchronization.
 
TThread.Synchronize
 
This method is blocking, which means that when you call Synchronize, the code blocks tills synchronize with the
main thread.
 
TThread.Queue
 
This method is non blocking, so when you call queue, the message is queued and will be dispatched later.
 
 
Example Code
 
Update a Memo with the messages received from WebSocket Client.
 

procedure OnClientMessage(Connection: TsgcWSConnection; Text: String);


begin
  TThread.Queue(nil,

42
QUICKSTART

    procedure
begin
          memo1.lines.add(Text);
end);
end;

43
QUICKSTART

QuickStart | Build
Build an application with sgcWebSockets library is very easy, only keep in mind if your components require
openSSL libraries or not. If your applications require secure connections, openSSL libraries must be deployed (ex­
cept if you use SChannel for windows on Client Components).
 
For windows applications, is enough to deploy the openSSL libraries in the same folder where application is lo­
cated.
 
For other personalities check the following articles:
 
• Build OSX Application
• Build Android Application
• Build iOS Application

44
QUICKSTART

Build | OSX Application


In order to build a OSX Application with sgcWebSockets library you must follow the steps from Embarcadero web­
site to build a OSX Application.
 
Install PASServer in MacOS
 
http://docwiki.embarcadero.com/RADStudio/Sydney/en/PAServer,_the_Platform_Assistant_Server_Application
 
Obtain a Developer ID Certificate
 
Login with a valid Apple Developer Account to https://developer.apple.com and create a new "Developer ID Appli­
cation" from Certificates menu.
 
http://docwiki.embarcadero.com/RADStudio/Rio/en/MacOS_Notarization
 
Create a new Apple Id
 
Then go to https://appleid.apple.com/account to create a new Apple Id
 
Configure Provisioning
 
Finally, open the menu Project / Options / Provisioning and fill the required data to notarize a OSX Application.
 

If your project requires some libraries, don't forget to include in the menu Project / Deployment. Set Remote Path
to "Contents\MacOS\"
 

 
These libraries will be automatically signed when the application is notarized, you can check if the library has been
signed using the following command:

codesign -dv --verbose=4 libcrypto.1.1.dylib

45
QUICKSTART

Read more about How Configure openSSL OSX.

46
QUICKSTART

Build | Android Application


In order to build a Android Application with sgcWebSockets library you must follow the steps from Embarcadero
website to build an Android Application.
 
Creating an Android App
 
http://docwiki.embarcadero.com/RADStudio/Sydney/en/Creating_an_Android_App
 
 
Project Deployment
 
If your project requires some libraries, don't forget to include in the menu Project / Deployment. Set Remote Path
to ".\assets\internal"
 

 
Read more about How Configure openSSL Android.
 

47
QUICKSTART

Build | iOS Application


In order to build a iOS Application with sgcWebSockets library you must follow the steps from Embarcadero web­
site to build a iOS Application.
 
Install PASServer in MacOS
 
http://docwiki.embarcadero.com/RADStudio/Sydney/en/PAServer,_the_Platform_Assistant_Server_Application
 
Obtain a iOS Development Certificate
 
Login with a valid Apple Developer Account to https://developer.apple.com and create a new "iOS Development
Certificate" from Certificates menu.
Create a new Identifier for your iOS apps and a new provisioning profile.
 
http://docwiki.embarcadero.com/RADStudio/Sydney/en/IOS_Mobile_Application_Development
 
Configure Bundle Identifier
 
Open the menu Project / Options / Application / Version Info and set your Bundle Identifier
 

 
Deployment
 
If your project requires some static libraries, copy these libraries in the Embarcadero lib/iosDevice64 folder:
 
• C:\Program Files (x86)\Embarcadero\Studio\<IDE Version>\lib\iosDevice64\debug
• C:\Program Files (x86)\Embarcadero\Studio\<IDE Version>\lib\iosDevice64\release
 
Read more about How Configure openSSL iOS
 
Provisioning
 
Finally, check in the menu Project / Options / Deployment, if the certificate has been successfully loaded.
 

48
QUICKSTART

49
QUICKSTART

Fast Performance Servers


Servers based on Indy Library
TsgcWebSocketServer and TsgcWebSocketHTTPServer are based on Indy library, so every connection is handled
by a thread, so if you have 1000 concurrent connections, you will have, at least, 1000 threads to handle these con­
nections. When performance is important, you must do some "tweaks" to increase performance and improve server
work. From sgcWebSockets 4.3.3 Indy servers support IOCP too, you can read more.
 
Use the following tips to increase server performance.
 
1. Set in Server component property NotifyEvents := neNoSync. This means that events are raised in the context
of connection thread, so there is no synchronization mechanism. If you must access to VCL controls or shared ob­
jects, use your own synchronization mechanisms.
 
2. Set in Server component property Optimizations.Connections.Enabled := True. If you plan to have more than
1000 concurrent connections in your server, and you call Server.WriteData method a lot, enable this property. Basi­
cally, it saves connections in a cache list where searches are faster than accessing to Indy connections list.
 
2.1 CacheSize: is the number of connections stored in a fast cache. Default value = 100.
2.2 GroupLevel: creates internally several lists split by the first character, so if you have lots of connections,
searches are faster. Default value = 1.
 
3. Set in Server component property Optimizations.Channels.Enabled := True. Enabling this property, channels
are saved in a list where searches are faster than previous method.
 
4. Set in Server component property Optimizations.ConnectionsFree.Enabled := True. If this property is en­
abled, every time there is a disconnection, instead of destroying TsgcWSConnection, the object is stored in a List
and every X seconds, all objects stored in this list are destroyed.
 
4.1 Interval: number of seconds where all disconnected connections stored in a list are destroyed. By default
is 60.
 
5. By default, sgcWebSockets uses Critical Sections to protect access to shared objects. But you can use TMoni­
tor or SpinLocks instead of critical sections. Just compile your project with one of the following compiler defines
 
3.1 {$DEFINE SGC_SPINLOCKS}
3.2 {$DEFINE SGC_TMONITOR}
 
6. Use latest FastMM4, you can download from: https://github.com/pleriche/FastMM4
    FastMM4  is a very good memory manager, but sometimes doesn't scale well with multi-threaded applications.
Use the following compiler define in your application:
 
{$DEFINE UseReleaseStack}
 
    Then, add FastMM4 as the first unit in your project uses and compile again. For a high concurrent server, you will
note an increase in performance.
    This tweak does the following: If a block cannot be released immediately during a FreeMem call the block will be
added to a list of blocks that will be freed later, either in the background cleanup thread or during the next call to
FreeMem.
 
7. Better than FastMM4, use the latest FastMM5, you can download from: https://github.com/pleriche/FastMM5
    This is a new version from the same developer of FastMM4, support from Delphi XE3 Compiler and can used on
Windows32 and Windows64.
    FastMM5  is dual licensed, so there are 2 licenses: GPL and Commercial. So if you want use in commercial
projects, you must purchase a license
    Find below a grid which compares the performance between FastMM4 and FastMM5, doing 100.000 websocket
requests and responses using 1, 10, 100, 500 and 1000 concurrent clients. The performance under FastMM5 is
much better, in multithreaded applications, than using FastMM4.
 

50
QUICKSTART

Win­ Differ­
Clients FMM4 FMM5
dows ence
1 Win32 4135 4214 1,91%
  Win64 4052 4520 11,55%
10 Win32 4214 1729 -58,97%
  Win64 4104 1875 -54,31%
100 Win32 3958 1604 -59,47%
  Win64 3958 1614 -59,22%
500 Win32 4098 1723 -57,96%
  Win64 5333 1791 -66,42%
1000 Win32 5927 2208 -62,75%
  Win64 8166 2229 -72,70%
 
 

Server Based on HTTP.SYS


TsgcWebSocketServer_HTTPAPI component is based on Microsoft HTTP API and it's designed to work with IOCP,
so it's recommended when the server must handle thousands of connections but it has the limitation that can only
run on Windows.
 
The server can handle WebSocket and HTTP/2 protocols on the same port and can work with other implementa­
tions because it can be configured to only handle some endpoints.
Example: you can configure this server to handle websocket connections with our sgcWebSockets library and let
other implementations / third-parties or whatever use other endpoints.
 
• Endpoint: https://server/ws will handle connections that use WebSocket protocol using sgcWebSockets
• Endpoint: https://server/other willl handle connection using other library.
 
Use latest FastMM5, you can download from: https://github.com/pleriche/FastMM5
    This is a new version from the same developer of FastMM4, support from Delphi XE3 Compiler and can used on
Windows32 and Windows64.
    FastMM5  is dual licensed, so there are 2 licenses: GPL and Commercial. So if you want use in commercial
projects, you must purchase a license
    Find below a grid which compares the performance between FastMM4 and FastMM5, doing 100.000 websocket
requests and responses using 1, 10, 100, 500 and 1000 concurrent clients. The performance under FastMM5 is
much better, in multithreaded applications, than using FastMM4.
 
Win­ Differ­
Clients FMM4 FMM5
dows ence
1 Win32 5364 5182 -3,39%
  Win64 5057 5026 -0,61%
10 Win32 4922 1744 -64,57%
  Win64 4958 1770 -64,30%
100 Win32 3359 1682 -49,93%
  Win64 3979 1536 -61,40%
500 Win32 2364 1890 -20,05%
  Win64 2901 1666 -42,57%
1000 Win32 3296 1968 -40,29%
  Win64 4469 1989 -55,49%
 
 

51
QUICKSTART

Memory Manager
Recently a new version of FastMM, developed by Pierre le Riche, has been released, the new version is
called FastMM5 and has been rewritten to improve the performance on multi threaded applications, can be config­
ured for better speed or less memory usage and more.

Support from Delphi XE3 Compiler and can used on Windows32 and Windows64.

FastMM5 is dual licensed, so there are 2 licenses: GPL and Commercial. So if you want use in commercial
projects, you must purchase a license. More details here

https://github.com/pleriche/FastMM5

FastMM4 has a new fork, called FastMM4-AVX, developed by Maxim  Masiutin, which  adds very interesting fea­
tures like: more efficient synchronization, AVX instructions for faster memory copy, speed improvements and more.
FastMM4-AVX is dual licensed: MPL and GPL. More details here:

https://github.com/maximmasiutin/FastMM4-AVX

Configuration
In order to test the performance with our components, a new windows console application has been created, sgcBenchmark
which will be used to measure the performance of every memory manager using our sgcWebSockets components.

The test is very simple, a client (or more than one client) connects to a server, sends a message to server and
server replies with the same message to client. This is repeated 100.000 times. The tests are repeated changing
the number of concurrent clients, first 1, then 10, 100... the measured time is the time elapsed between the first
message sent by client and the last message received from server (so the time used to connect to server is not
measured).

The benchmark will compare the performance using the Default Memory Manager that comes with Delphi 10.4.1,
FastMM5 and FastMM4-AVX

Benchmark Indy WebSocket Server


In the first Benchmark, the Server used is the Indy WebSocket Server, this server is based on Indy TCP Server, so
every connection creates 1 thread. 

The values are measured in milliseconds, so for example, the first test that is done with 1 client in Windows32 plat­
forms, using the default memory manager takes 4135 milliseconds, using FastMM5 takes 4214 milliseconds and
using FastMM4-AVX takes 4823 milliseconds. The percentage calculated is against the reference value, in this
case against the Default memory manager that comes with delphi, as much lower is the percentage, better perfor­
mance has.

The Benchmark has been done 3 times and the values showed are the sum of the benchmarks / 3.

For the benchmark, the server used was:

• Windows 2016 Server Datacenter


• 16 Virtual Processors
• 32 GB RAM
• 2.2 GHz

The Delphi version used was Delphi 10.4.1, and the latest FastMM5  and FastMM4-AVX versions from github
servers.

Find below the result of the benchmark.

52
QUICKSTART

Clients Plat­ Default FMM5 FMM5 FMM4-AVX FMM4-AVX


form  (ms) (ms) (%) (ms) (%)

1 Win32 4135 4214 1.91% 4823 16.64%

1 Win64 4052 4520 11.55% 4328 6.81%

10 Win32 4214 1729 -58.97% 1828 -56.62%

10 Win64 4104 1875 -54.31% 1651 -59.77%

100 Win32 3958 1604 -59.47% 1583 -60.01%

100 Win64 3958 1614 -59.22% 1635 -58.69%

500 Win32 4098 1723 -57.96% 1854 -54.76%

500 Win64 5333 1791 -66.42% 1833 -65.63%

1000 Win32 5927 2208 -62.75% 2328 -60.72%

1000 Win64 8166 2229 -72.70% 2234 -72.64%

Benchmark HTTP.SYS Server


In the second Benchmark, the Server used is the HTTP.SYS WebSocket Server, this server is based on HTTP API
Microsoft Framework and the connections are handled by a pool of threads.

The values are measured in milliseconds, so for example, the first test that is done with 1 client in Windows32 plat­
forms, using the default memory manager takes 5364 milliseconds, using FastMM5 takes 5182 milliseconds and
using FastMM4-AVX takes 5838 milliseconds. The percentage calculated is against the reference value, in this
case against the Default memory manager that comes with Delphi, as much lower is the percentage, better perfor­
mance has.

The Benchmark has been done 3 times and the values showed are the sum of the benchmarks / 3.

For the benchmark, the server used was:

• Windows 2016 Server Datacenter


• 16 Virtual Processors
• 32 GB RAM
• 2.2 GHz

The Delphi version used was Delphi 10.4.1, and the latest FastMM5  and FastMM4-AVX versions from github
servers.

Find below the result of the benchmark.

Clients Plat­ Default FMM5 FMM5 FMM4-AVX FMM4-AVX


form  (ms) (ms) (%) (ms) (%)

1 Win32 5364 5182 -3.39% 5838 8.84%

53
QUICKSTART

1 Win64 5507 5206 -0.61% 5135 1.54%

10 Win32 4922 1744 -64.57% 2088 -57.58%

10 Win64 4958 1770 -64.30% 1953 -60.61%

100 Win32 3359 1682 -49.93% 2244 -33.19%

100 Win64 3979 1536 -61.40% 1859 -53.28%

500 Win32 2364 1890 -20.05% 2344 -0.85%

500 Win64 2901 1666 -42.57% 1859 -35.92%

1000 Win32 3296 1968 -40.29% 2531 -23.21%

1000 Win64 4469 1989 -55.49% 2047 -54.20%

Comments about Benchmarks


Find below some comments about the results obtained after benchmark the 3 different memory managers:

• Using in single threaded application, there are no big differences in performance between FastMM4, Fast­
MM5 and FasMM4-AVX.
• FastMM5 and FastMM4-AVX work much better in multithreaded applications.
• The differences between FastMM5 and FastMM4­AVX are small, at least doing these benchmarks.
• Windows 32 benchmarks performs better than Windows 64 tests. Using FastMM5 or FastMM4­AVX in a 
Windows 64 applications improves performance more than in Windows 32.
 
The final decision to choose one memory manager or another depends of the project, I think there is no single
memory manager that works as the best in all conditions, so before choose one or another, test, test and test again
to see which performance better for your needs
 

54
QUICKSTART

OpenSSL
OpenSSL is a software library for applications that secure communications over computer networks against eaves­
dropping or need to identify the party at the other end. It is widely used by Internet servers, including the majority of
HTTPS websites.
 
This library is required by components based on Indy Library when a secure connection is needed. If your applica­
tion requires OpenSSL, you must have necessary files in your file system before deploying your application:
 
Currently, sgcWebSockets supports: 1.0.2, 1.1 and 3.0 openSSL versions.
 
Static/Dynamic
Platform API 1.0 API 1.1 API 3.0
Linking
libeay32.dll
Windows (32- libcrypto-1_1.dll and libcrypto-3.dll and
and Dynamic
bit and 64-bit) libssl-1_1.dll libssl-3.dll
ssleay32.dll
libcrypto.dylib, libcrypto.1.1.dylib, libcrypto.3.dylib,
OSX Dynamic
libssl.dylib libssl.1.1.dylib libssl.3.dylib
iOS Device
libcrypto.a libcrypto.a and
(32-bit and libcrypto.a and libssl.a Static
and libssl.a libssl.a
64-bit)
libcrypto.dylib, libcrypto.1.1.dylib, libcrypto.3.dylib,
iOS Simulator Dynamic
libssl.dylib libssl.1.1.dylib libssl.3.dylib
Android De­ libcrypto.so,
libcrypto.so, libssl.so libcrypto.so, libssl.so Dynamic
vice libssl.so
 
 
Find below how configure openSSL libraries for every Personality:
 
• Windows
• OSX
• Android
• iOS
 

openSSL Configurations
sgcWebSockets Indy based components allows to configure some openSSL properties. Access to the following
properties:
 
• Server Components: SSLOptions.OpenSSL_Options.
• Client Components: TLSOptions.OpenSSL_Options.
 
API Version
 
Standard Indy library only allow to load 1.0.2 openSSL libraries, these libraries have been deprecated and latest
openSSL releases use 1.1.1 API.
sgcWebSockets Enterprise allows to load 1.1.1 openSSL libraries, you can configure in this property which
openSSL API version will be loaded. Only one API version can be loaded by process (so you can't mix openSSL
1.0.2 and 1.1.1 libraries in the same application).
 
 
LibPath
 
This property allows to set the location of openSSL libraries. This is useful for Android or OSX projects, where the
location of the openSSL libraries must be set.

55
QUICKSTART

Accepts the following values:


 
• oslpNone: this value doesn't set any library path value (is the value by default).
• oslpDefaultFolder: this value sets the default folder of openSSL libraries. This path is different for every
personality (windows, osx...).
 
 

Self-Signed Certificates
You can use self-signed certificates for testing purposes, you only need to execute the following command to create
a self-signed certificate
 

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem

It will create 2 files: cert.pem (certificate) and key.pem (private key). You can combine both files in a single one.
Just create a new file and copy the content of both files on the new file. So you will have an structure like this:
 
-----BEGIN PRIVATE KEY-----
....
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
 

Common Errors

SSL_GET_RECORD: wrong version number


 
This error means that the server and the client are using a different version of SSL/TLS protocol, to fix it, try to set
the correct version in Server and/or client component
 
Server.SSLOptions.Version
Client.TLSOptions.Version
 
SSL3_GET_RECORD: decryption failed or bad record mac
 
Usually these error is raised when:
 
1. Check that you are using the latest OpenSSL version, if is too old, update to latest supported.
2. If this error appears randomly, usually is because more than one thread is accessing to the OpenSSL connec­
tion. You can try to set NotifyEvents = neNoSync which means that the events: OnConnect, OnDisconnect, OnMes­
sage... will be fired in the context of thread connection, this avoids some synchronization problems and provides
better performance. As a down side, if for example you are updating a visual control in a form when you receive a
message, you must implement your own synchronization methods because visual controls are not thread-safe.

56
QUICKSTART

OpenSSL | Windows
There is one version for 32 bits and another for 64 bits. You must copy these libraries in the same folder where is
your application or in your system path.
If your Operating System is Windows 32 bits, just copy in System32 folder.
If your Operating System is Windows 64 bits, copy 64 bits version in System32 folder and 32 bits version in Sys­
Wow64 folder.

API 1.0

Requires the following libraries:


 
• libeay32.dll
• ssleay32.dll
 
If your Operating System is Windows 32 bits, just copy in System32 folder.
If your Operating System is Windows 64 bits, copy 64 bits version in System32 folder and 32 bits version in Sys­
Wow64 folder.
 
You can download latest libraries from your account (libraries don't have external dependencies and are digitally
signed).

API 1.1

Requires the following libraries:


 
• libcrypto-1_1.dll
• libssl-1_1.dll
 
If your Operating System is Windows 32 bits, just copy in System32 folder.
If your Operating System is Windows 64 bits, copy 64 bits version in System32 folder and 32 bits version in Sys­
Wow64 folder.
 
You can download latest libraries from your account (libraries don't have external dependencies and  are digitally
signed).
 
 

API 3.0

Requires the following libraries:


 
• libcrypto-3.dll
• libssl-3.dll
 
If your Operating System is Windows 32 bits, just copy in System32 folder.
If your Operating System is Windows 64 bits, copy 64 bits version in System32 folder and 32 bits version in Sys­
Wow64 folder.
 
You can download latest libraries from your account (libraries don't have external dependencies and  are digitally
signed).
 
 

57
QUICKSTART

OpenSSL | OSX
Newer versions of OSX doesn't include openssl libraries or are too old, so you must deploy with your application.
Deploy these libraries using following steps:
 
• Open Project/Deployment in your project.
• Add required libraries.
• Set RemotePath  = 'Contents\Macos\'.
• Configure the openSSL LibPath to default folder:
• Client.TLSOptions.OpenSSL_Options.LibPath = oslpDefaultFolder.
• Server.SSLOptions.OpenSSL_Options.LibPath = oslpDefaultFolder.

API 1.0

Requires the following libraries:


 
• libcrypto.dylib
• libssl.dylib
 
You can download latest libraries from your account.
 

API 1.1

Requires the following libraries:


 
• libcrypto.1.1.dylib
• libssl.1.1.dylib
 
There is one version for 32 bits and another for 64 bits. You must copy these libraries in the same folder where is
your application.
You can download latest libraries from your account.
 
 

API 3.0

Requires the following libraries:


 
• libcrypto.3.dylib
• libssl.3.dylib
 
Only 64bits version are provided. You must copy these libraries in the same folder where is your application
You can download latest libraries from your account.
 
 
 
If you include the openSSL libraries in a OSX application, after the application has been Notarized, the libraries will
be signed, you can check this using the following command:

codesign -dv --verbose=4 libcrypto.1.1.dylib

Check the following video which shows how Build a MacOSX64 Application with openSSL libraries
 
https://www.esegece.com/websockets/videos/delphi/quickstart/275-build-macosx64-application/file
 
 

58
QUICKSTART

Errors

Clients should not load the unversioned libcrypto dylib as it does not have a stable ABI.
 
On MacOS Monterey+, you can get this error trying to load the openSSL libraries, the error happens when tries to
load first the openSSL libraries without version (libcrypto.dylib for example).
To fix this error set in the property OpenSSL_Options.UnixSymLinks the value oslsSymLinksDontLoad. This
avoids the loading of the openSSL libraries without version.

59
QUICKSTART

OpenSSL | Android
Newer versions of Android doesn't include openssl libraries or are too old, so you must deploy with your applica­
tion. Deploy these libraries using following steps:
 
• Open Project/Deployment in your project.
• Add required libraries.
• Set RemotePath  = '.\assets\internal'.
• Configure the openSSL LibPath to default folder:
• Client.TLSOptions.OpenSSL_Options.LibPath = oslpDefaultFolder.
• Server.SSLOptions.OpenSSL_Options.LibPath = oslpDefaultFolder.

API 1.0

Requires the following libraries:


 
• libcrypto.so
• libssl.so
 
You can download latest libraries from your account.
 
 

API 1.1

Requires the following libraries:


 
• libcrypto.so
• libssl.so
 
You can download latest libraries from your account.
 
 

API 3.0

Requires the following libraries:


 
• libcrypto.so
• libssl.so
 
You can download latest libraries from your account.

60
QUICKSTART

OpenSSL | iOS
To install OpenSSL in a 64-bit iOS device, you must copy the libcrypto.a and libssl.a SSL library files to your sys­
tem. Download the .zip iOS OpenSSL, extract it and find the .a files in the \lib directory. You must copy the
libcrypto.a and libssl.a SSL library files to these directories:
 
• C:\Program Files (x86)\Embarcadero\Studio\<IDE Version>\lib\iosDevice64\debug
• C:\Program Files (x86)\Embarcadero\Studio\<IDE Version>\lib\iosDevice64\release
 
Add sgcIdSSLOpenSSLHeaders_static (or IdSSLOpenSSLHeaders if your sgcWebSockets edition is not Enter­
prise) unit to your uses clause.
 
If you need to deploy any file, you can set RemotePath = StartUp\Documents and to load the file use (requires add
System.IOUtils to uses clause):
 
TPath.GetDocumentsPath + PathDelim + <your filename>
 
The openSSL libraries must not be deployed using the menu Project/Deployment under iOS.
 

API 1.1

Modify IdCompilerDefines.inc and enable SGC_OPENSSL_API_1_1 in IOS section:


 
{$IFDEF IOS}
  {$DEFINE HAS_getifaddrs}
  {$DEFINE USE_OPENSSL}
  {$IFDEF CPUARM}
    // RLebeau: For iOS devices, OpenSSL cannot be used as an external library,
    // it must be statically linked into the app.  For the iOS simulator, this
    // is not true.  Users who want to use OpenSSL in iOS device apps will need
    // to add the static OpenSSL library to the project and then include the
    // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the
    // statically linked functions for the IdSSLOpenSSLHeaders unit to use...
    {$DEFINE STATICLOAD_OPENSSL}
// sgc--> enable for openssl API 1.1
{$DEFINE SGC_OPENSSL_API_1_1}
  {$ENDIF}
{$ENDIF}
 
You can download libraries from your account.
 
 

API 3.0

Modify IdCompilerDefines.inc and enable SGC_OPENSSL_API_1_1 in IOS section:


 
{$IFDEF IOS}
  {$DEFINE HAS_getifaddrs}
  {$DEFINE USE_OPENSSL}
  {$IFDEF CPUARM}
    // RLebeau: For iOS devices, OpenSSL cannot be used as an external library,
    // it must be statically linked into the app.  For the iOS simulator, this
    // is not true.  Users who want to use OpenSSL in iOS device apps will need
    // to add the static OpenSSL library to the project and then include the
    // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the
    // statically linked functions for the IdSSLOpenSSLHeaders unit to use...
    {$DEFINE STATICLOAD_OPENSSL}
// sgc--> enable for openssl API 1.1

61
QUICKSTART

{$DEFINE SGC_OPENSSL_API_1_1}
{$DEFINE SGC_OPENSSL_API_3_0}
  {$ENDIF}
{$ENDIF}
 
You can download libraries from your account.

62
QUICKSTART

Indy
Indylibrary is an open source client/server communications library that supports TCP/UDP/RAW sockets, as well as
over 100 higher level protocols including SMTP, POP3, IMAP, NNTP, HTTP, FTP, and many more. Indy is written in
Delphi but is also available for C++Builder and FreePascal. sgcWebSockets uses Indy as a base for some compo­
nents and the different sgcWebSockets Editions make a different use of the Indy library.
 
sgcWebSockets supports protocols like HTTP/2 which require the use of ALPN, can use TLS 1.3 using openSSL
1.1.1 or openSSL 3.0.0... all these features are not supported by standard Indy library, so sgcWebSockets Enter­
prise edition includes a custom Indy library which supports this features. To avoid uninstall the standard Indy library
from the IDE, the required Indy files are renamed adding the prefix "sgc", so for example: the unit "IdGlobal" is re­
named to "sgcIdGlobal". This way, both versions can coexist without problems.
 
Find below which Indy version is used by every sgcWebSockets Edition:
 
sgcWebSockets Edition Indy Version
STANDARD Standard
PROFESSIONAL Standard
ENTERPRISE Custom
 
Customers with a "Registered" licenses, are old licenses before the sgcWebSockets package was splitted, will find
the following sgcWebSockets package versions:
 
sgcWebSockets Edition Indy Version
sgcWebSockets Standard
sgcWebSockets min Standard
sgcWebSockets min Indy* Custom
 
*The sgcWebSockets_min_indy is the same that sgcWebSockets Enterprise edition.
 
The use of the custom indy version, is defined in the file "sgcVer.inc" located in the source folder. There is a compil­
er define called "SGC_CUSTOM_INDY" which enables or disables the use of this indy version. If you have a Enter­
prise Edition and want to disable the use of the custom indy, just delete the following compiler define:
 
{$DEFINE SGC_CUSTOM_INDY}
 
Of course, if you enable SGC_CUSTOM_INDY but you don't have in the source folder the required custom indy
version units, this compiler define won't work.
 

sgcIndy package
The use of the custom indy version is not limited to the sgcWebSockets components. Some customers want to
make use of the new features of this custom indy version, in standard Indy components like SMTP for example, so
they use TLS 1.3 when sending emails, using FTP servers... The sgcWebSockets Enterprise edition, provides an
additional full Indy package with all these features. This package, called "sgcIndy package", includes the full Indy li­
brary with support for openSSL 1.1.1 and openSSL 3.0.0. So you first must uninstall your current Indy library in­
stalled in your IDE and then install this version, the process to install the sgcIndy package it's exactly the same that
any Indy library (here the units are not renamed).
 
When you want to use openSSL libraries, just set the global variable OPENSSL_API_VERSION to the desired
opensSSL API Version before loading openSSL libraries. This global variable is in the unit IdSSLOpenSSLHeaders.
 
Example: to use the openSSL 1.1.1 libraries
 
OPENSSL_API_VERSION := opSSL_1_1;
 

63
TOPICS

WebSocket Events
WebSocket connections have the following events:
 
OnConnect
The event raised when a new connection is established.
 
OnDisconnect
The event raised when a connection is closed.
 
OnError
The event raised when a connection has any error.
 
OnMessage
The event raised when a new text message is received.
 
OnBinary
The event raised when a new binary message is received.
 
 
By default, sgcWebSockets uses an asynchronous mechanism to raise these events, when any of these events is
raised internally, it queues this message and is dispatched by the operating system when is allowed. This behav­
iour can be modified using a property called NotifyEvents, by default neAsynchronous is selected, if neNoSync
is checked then events will be raised without synchronizing with the main thread (if you need to update any VCL
control or access to shared resources, then you will need to implement your own synchronizing method).
 
neNoSync is recommended when:
 
1. You need to handle a lot of messages on a very short period of time.
2. Your project is built for command line (if you don't set neNoSync, you won't get any event).
3. Your project is a library.
 
If no, then you can set default property to neAsynchronous.

64
TOPICS

WebSocket Parameters Connection


Supported by
 
  TsgcWebSocketClient
  Java script
 
Sometimes is useful to pass parameters from client to server when a new WebSocket the connection is estab­
lished. If you need to pass some parameters to the server, you can use the following property:
 
  Options / Parameters
 
By default, is set to '/', if you need to pass a parameter like id=1, you can set this property to '/?id=1'
 
On Server Side, you can handle client parameters using the following parameter:

procedure WSServerConnect(Connection: TsgcWSConnection);


begin
  if Connection.URL = '/?id=1' then
    HandleThisParameter;
end;

 
Using Javascript, you can pass parameters using connection url, example:
 

<script src="http://localhost/sgcWebSockets.js" type="text/javascript"></script>


<script type="text/javascript">var socket = new sgcWebSocket('ws://localhost/?id=1');</script>

 
 

65
TOPICS

Using inside a DLL


If you need to work with Dynamic Link Libraries (DLL) and sgcWebSockets (or console applications), NotifyEvents
property needs to be set to neNoSync.
 

66
TOPICS

WebBrowser Test
TsgcWebSocketServer implements a built-in Web page where you can test WebSocket Server connection with your
favourite Web Browser.
 
To access to this Test Page, you need to type this URL:
 
  http://host:port/sgcWebSockets.html
 
Example: if you have configured your WebSocket Server on IP 127.0.0.1 and uses port 80, then you need to type:
 
  http://127.0.0.1:80/sgcWebSockets.html
 
In this page, you can test the following WebSocket methods:
 
  Open
  Close
  Status
  Send
 
To disable WebBrowser HTML Test pages, just set in TsgcWebSocketServer.Options.HTMLFiles = false;

67
TOPICS

Custom Sub-Protocols
A client can request that the server use a specific subprotocol by including the subprotocol name in its handshake.
If it is specified, the server needs to include one of the selected subprotocol values in its response for the connec­
tion to be established.
 
In order to create your own subprotocol, you must inherit from TsgcWSProtocol_Client_Base and
TsgcWSProtocol_Server_Base in order to create your custom subprotocols.
 

//Client Example Code


 
unit sgcWebSocket_Protocol_Example_Client;
 
interface
 
{$I sgcVer.inc}
{$IFDEF SGC_PROTOCOLS}
 
uses
  sgcWebSocket_Protocol_Base_Client, Classes, sgcWebSocket_Classes;
 
type
  TsgcWSProtocol_Example_Client = class(TsgcWSProtocol_Client_Base)
  { from TsgcWSComponent }
  protected
    procedure DoEventConnect(aConnection: TsgcWSConnection); override;
    procedure DoEventMessage(aConnection: TsgcWSConnection; const Text: string);
        override;
    procedure DoEventDisconnect(aConnection: TsgcWSConnection; Code: Integer);
        override;
  { from TsgcWSComponent }
  public
    constructor Create(aOwner: TComponent); override;
  end;
{$ENDIF}
 
implementation
 
{$IFDEF SGC_PROTOCOLS}
 
constructor TsgcWSProtocol_Example_Client.Create(aOwner: TComponent);
begin
  inherited;
  // ... here add your protocol name
  FProtocol := 'MyProtocol';
end;
 
procedure TsgcWSProtocol_Example_Client.DoEventConnect(aConnection:
    TsgcWSConnection);
begin
  inherited;
  // ... add your own code when client connects to server
end;
 
procedure TsgcWSProtocol_Example_Client.DoEventDisconnect(aConnection:
    TsgcWSConnection; Code: Integer);
begin
  // ... add your own code when client disconnects from server
  inherited;
end;
 
procedure TsgcWSProtocol_Example_Client.DoEventMessage(aConnection:
    TsgcWSConnection; const Text: string);
begin
  // ... process messages received from server
  // ... you can send a message to server using WriteData('your message') method
end;
{$ENDIF}
 

68
TOPICS

end.
 
// Server Example Code
 
unit sgcWebSocket_Protocol_Example_Server;
 
interface
 
{$I sgcVer.inc}
{$IFDEF SGC_PROTOCOLS}
 
uses
  sgcWebSocket_Protocol_Base_Server, Classes, sgcWebSocket_Classes;
 
type
  TsgcWSProtocol_Example_Server = class(TsgcWSProtocol_Server_Base)
  { from TsgcWSComponent }
  protected
    procedure DoEventConnect(aConnection: TsgcWSConnection); override;
    procedure DoEventMessage(aConnection: TsgcWSConnection; const Text: string);
        override;
    procedure DoEventDisconnect(aConnection: TsgcWSConnection; Code: Integer);
        override;
  { from TsgcWSComponent }
  public
    constructor Create(aOwner: TComponent); override;
  end;
{$ENDIF}
 
implementation
 
{$IFDEF SGC_PROTOCOLS}
constructor TsgcWSProtocol_Example_Server.Create(aOwner: TComponent);
begin
  inherited;
  // ... here add your protocol name
  FProtocol := 'MyProtocol';
end;
 
procedure TsgcWSProtocol_Example_Server.DoEventConnect(aConnection:
    TsgcWSConnection);
begin
  inherited;
  // ... add your own code when a client connects to server
end;
 
procedure TsgcWSProtocol_Example_Server.DoEventDisconnect(aConnection:
    TsgcWSConnection; Code: Integer);
begin
  // ... add your own code when a client disconnects from server
  inherited;
end;
 
procedure TsgcWSProtocol_Example_Server.DoEventMessage(aConnection:
    TsgcWSConnection; const Text: string);
begin
  inherited;
  // ... process messages received from clients
  // ... you can answer to client using WriteData(aConnection.Guid, 'your message') method
  // ... you can send a message to all clients using BroadCast('your message') method
end;
{$ENDIF}
 
end.
 
//Implementation
// Once your custom subprotocol is implemented, then you only need to assign to your Client or Server websocket componen
 
procedure InitalizeClient;
var
  oClient: TsgcWebSocketClient;
  oProtocol: TsgcWSProtocol_Example_Client;
begin
  oClient := TsgcWebSocketClient.Create(nil);
  oProtocol := TsgcWSProtocol_Example_Client.Create(nil);
  oProtocol.Client := oClient;
end;
 
 
procedure InitalizeServer;
var
  oServer: TsgcWebSocketServer;
  oProtocol: TsgcWSProtocol_Example_Server;
begin
  oClient := TsgcWebSocketServer.Create(nil);
  oProtocol := TsgcWSProtocol_Example_Server.Create(nil);

69
TOPICS

  oProtocol.Server := oServer;
end;

70
TOPICS

Authentication
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketClient
  Java script (*only URL Authentication is supported)
 
 
WebSockets Specification doesn't have any authentication method and Web Browsers implementation don't allow
to send custom headers on new WebSocket connections.
 
To enable this feature you need to access to the following property:
 
 Authentication/ Enabled
 
 
sgcWebSockets implements 3 different types of WebSocket authentication:
 
Session: client needs to do an HTTP GET passing username and password, and if authenticated, server re­
sponse a Session ID. With this Session ID, client open WebSocket connection passing as a parameter. You
can use a normal HTTP request to get a session id using and passing user and password as parameters
 
http://host:port/sgc/req/auth/session/:user/:password
 
example: (user=admin, password=1234) --> http://localhost/sgc/req/auth/session/admin/1234
 
This returns a token that is used to connect to server using WebSocket connections:
 
    ws://localhost/sgc/auth/session/:token
 
 
URL: client open WebSocket connection passing username and password as a parameter.
 
              ws://host:port/sgc/auth/url/username/password
 
example: (user=admin, password=1234) --> http://localhost/sgc/auth/url/admin/1234
 
 
Basic: implements Basic Access Authentication, only applies to VCL Websockets (Server and Client) and
HTTP Requests (client Web Browsers don't implement this type of authentication). When a client tries to
connect, it sends a header using AUTH BASIC specification.
 
 
You can define a list of Authenticated users, using Authentication/ AuthUsers property. You need to define every
item following this schema: user=password. Example:
 
admin=admin
user=1234
....
 
There is an event called OnAuthentication where you can handle authentication if the user is not in AuthUsers list,
client doesn't send an authorization request... You can check User and Password params and if correct, then set
Authenticated variable to True. example:
 

procedure WSServerAuthentication(Connection: TsgcWSConnection; aUser, aPassword: string; var Authenticated: Boolean)


begin
  if (aUser = 'John') and (aPassword = '1234') then

71
TOPICS

    Authenticated := True;
end;

 
 

72
TOPICS

Secure Connections
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketClient
  Web Browsers
 
SSL support is based on Indy implementation, so you need to deploy openssl libraries in order to use this feature.
TsgcWebSocketClient supports Microsoft SChannel, so there is no need to deploy openssl libraries for windows 32
and 64 bits if SChannel option is selected in WebSocket Client.
 
 
Server Side
 
To enable this feature, you need to enable the following property:
 
SSL/ Enable
 
There are other properties that you need to define:
 
SSLOptions/ CertFile/ KeyFile/ RootCertFile: you need a certificate in .PEM format in order to encrypt
websocket communications.
 
SSLOptions/ Password: this is optional and only needed if the certificate has a password.
 
SSLOptions/ Port: port used on SSL connections.
 
 
 
Client Side
 
To enable this feature, you need to enable the following property:
 
TLS/ Enable
 
 
OpenSSL
 
By default, client and server components based on Indy make use of openSSL libraries when connect to secure
websocket servers.
Indy only supports 1.0.2 openssl API so API 1.1 is not supported. If you compile sgcWebSockets with our custom
Indy library you can make use of API 1.1 and select TLS 1.3 version. Just select in OpenSSL_Options properties
which openSSL API would you use:
 
• oslAPI_1_0: it's default indy API, you can use standard Indy package with openssl 1.0.2 libraries.
• oslAPI_1_1: only select if you are compiling sgcWebSockets with our custom Indy library (Enterprise Edi­
tion). Will use openssl 1.1.1 libraries.
• oslAPI_3_0: only select if you are compiling sgcWebSockets with our custom Indy library (Enterprise Edi­
tion). Will use openssl 3.0.0 libraries.
• ECDHE: allows to enable ECDHE for TLS 1.2 (more secure connections).
 
 
Events
 
There are 2 events which can be used to customize your SSL settings:

73
TOPICS

OnSSLGetHandler
This event is raised before SSL handler is created, you can create here your own SSL Handler (needs to be inherit­
ed from TIdServerIOHandlerSSLBase or TIdIOHandlerSSLBase) and set the properties needed

procedure OnServerSSLGetHandler(Sender: TObject; aType: TwsSSLHandler; var aSSLHandler:


TIdServerIOHandlerSSLBase);
begin
  aSSLHandler := TCustomSSLHandler.Create(nil);
  ...
end;

OnSSLAfterCreateHandler
If no custom SSL object has been created, it creates by default using OpenSSL handler. You can access to SSL
Handler properties and modify if needed

procedure OnSSLAfterCreateHandler(Sender: TObject; aType: TwsSSLHandler; aSSLHandler:


TIdServerIOHandlerSSLBase);
begin
  TIdServerIOHandlerSSLOpenSSL(aSSLHandler).SSLOptions.Method := sslvTLSv1_2;
end;

 
 
Microsoft SChannel
 
From sgcWebSockets 4.2.6 you can use SChannel instead of openssl (only for windows from Windows 7+). This
means there is no need to deploy openssl libraries. TLS 1.0 is supported from windows 7 but if you need more
modern implementations like TLS 1.2 in Windows 7 you must enable TLS 1.1 and TLS 1.2 in Windows Registry.
Requires Delphi 2010 Professional Edition (or Enterprise Edition for Delphi 7, 2007 and 2009).

74
TOPICS

HeartBeat
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketServer_HTTPAPI
  TsgcWebSocketClient
 
On Server components, automatically sends a ping to all active WebSocket connections every x seconds.
 
On Client components, automatically sends a ping to the server every x seconds.
 
HeartBeat has the following properties:
 
• Enabled: if true, sends a ping
• Interval: is the value in seconds when a ping will be sent. Example: if value is 10, a ping will be sent every
10 seconds
• Timeout: is the time will wait a response from server. Example: if value is 30, means will wait 30 seconds to
receive a response before close connection.
 
 
Customize HeartBeat
 
Client and server components allow customize HeartBeat to send custom pings and control that connection is still
alive. The event OnBeforeHeatBeat is built exactly for that, allows to send a custom message and/or not send stan­
dard ping.
 
Example: send a message text as a ping every 30 seconds.
 

procedure OnBeforeHeartBeat(Sender: TObject; const Connection: TsgcWSConnection; var Handled: Boolean);


begin
  Connection.WriteData('ping');
  Handled := True;
end;

75
TOPICS

WatchDog
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketServer_HTTPAPI
  TsgcWebSocketClient
 

Server
On Server components, automatically restart server after unexpected shutdown. To check if server is active every
60 seconds, just set the following properties:
 
WatchDog.Enabled = true;
WatchDog.Interval = 60;
WatchDog.Attempts = 0;
 
WatchDog.Monitor allows to verify if new clients can connect to server, this is done by an internal client that tries to
open a WebSocket connection to server, if fails, it restart the server. To monitor if clients can connect to server with
a Time Out of 10 seconds, set the following properties:
 
WatchDog.Enabled = true;
WatchDog.Interval = 60;
WatchDog.Attempts = 0;
WatchDog.Monitor.Enabled = true;
WatchDog.Monitor.TimeOut = 10;

Client
On Client components, automatically reconnect to server after unexpected disconnection. To reconnect after a dis­
connection every 10 seconds, just set the following properties:
 
WatchDog.Enabled = true;
WatchDog.Interval = 10;
WatchDog.Attempts = 0;

76
TOPICS

Logs
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketClient
 
 
This is a useful feature that allows debugging WebSocket connections, to enable this, you need to access to the
following property:
 
LogFile/ Enabled
 
Once enabled, every time a new connection is established it will be logged in a text file. On Server component, if
the file it's not created it will be created but with you can't access until the server is closed, if you want to open log
file while the server is active, log file needs to be created before start server.
 
Example:
 

127.0.0.1:49854 Stat Connected.


 
127.0.0.1:49854 Recv 09/11/2013 11:17:03: GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:5414
Origin: http://127.0.0.1:5414
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: 1n598ldHs9SdRfxUK8u4Vw==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
 
127.0.0.1:49854 Sent 09/11/2013 11:17:03: HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: gDuzFRzwHBc18P1CfinlvKv1BJc=
 
127.0.0.1:49854 Stat Disconnected.
0.0.0.0:0 Stat Disconnected.

WebSocket Messages
 
WebSocket frames can be masked, which means that the message logged can not be read.
When the property LogFile.UnMaskFrames = True (by default it's true)
 
• Messages sent by WebSocket Client are saved as unmasked.
• Messages received by WebSocket Server are saved masked and unmasked (the reason is that when the
socket reads the buffer, it doesn't know if the protocol of the message, so it saves both).
 
 

77
TOPICS

HTTP
Supported by
 
  TsgcWebSocketHTTPServer
 
 
TsgcWebSocketHTTPServer is a component that allows handling WebSocket and HTTP connections using the
SAME port. Is very useful when you need to set up a server where only HTTP port is enabled (usually 80 port). This
component supports all TsgcWeBSocketServer features and allows to serve HTML pages.
 
You can serve HTML pages statically, using DocumentRoot property, example: if you save test.html in directory
"C:\inetpub\wwwroot", and you set DocumentRoot to "C:\inetpub\wwwroot". If a client tries to access to test.html, it
will be served automatically, example:
 
  http://localhost/test.html
 
 
Or you can serve HTML or other resources dynamically by code, to do this, there is an event called OnCom­
mandGet that is fired every time a client requests a new HTML page, image, javascript file... Basically, you need to
check which document is requesting client (using ARequestInfo.Document) and send a response to client (using
AResponseInfo.ContentText where you send response content, AResponse.ContentType which is the type of re­
sponse and a AResponseInfo.ResponseNo with a number of response code, usually is 200), example:
 

procedure WSServerCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;


  AResponseInfo: TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document = '/myfile.js' then
  begin
    AResponseInfo.ContentText := '<script type="text/javascript">alert("Hello!");</script>';
    AResponseInfo.ContentType := 'text/javascript';
    AResponseInfo.ResponseNo := 200;
  end
end;

78
TOPICS

Broadcast and Channels


Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketServer_HTTPAPI
 
Broadcast method by default send message to all clients connected, but you can use channels argument to fil­
ter and only broadcast message to clients subscribed to a channel.
 
Example: your server has 2 types of connected clients, desktop and mobile devices, so you can create 2 channels
"desktop" and "mobile".
 
If you can identify in OnConnect event of server if a client is mobile, you can do something like following.

procedure OnServerConnect(Connection: TsgcWSConnection);


begin
  if desktop then
    TsgcWSConnectionServer(Connection).DoSubscribe('desktop');
end;

 
First cast Connection to TsgcWSConnectionServer to access subscription methods and if fits your filter, will be sub­
scribed to desktop channel. Subscription to a channel can be done in any event, example, you can ask to client to
tell you if it's mobile or not and send a message from client to server with info about client. Then you can only
broadcast to desktop connections:

Server.Broadcast('Your text message', 'desktop');

 
If you have 100 connections and 30 are mobile, message will be only sent to other 70.

79
TOPICS

Bindings
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
 
 
Usually, Servers have more than one IP, if you enable a WebSocket Server and set listening port to 80, when the
server starts, tries to listen port 80 of ALL IP, so if you have 3 IP, it will block port 80 of each IP's.
 
Bindings allow defining which exact IP and Port are used by the Server. Example, if you need to listen on port 80
for IP 127.0.0.1 (internal address) and 80.254.21.11 (public address), you can do this before the server is activated:
 

With WSServer.Bindings.Add do
begin
  Port := 80;
  IP := '127.0.0.1';
end;
With WSServer.Bindings.Add do
begin
  Port := 80;
  IP := '80.254.21.11';
end;

 
 

80
TOPICS

Post Big Files


Supported by
 
  TsgcWebSocketHTTPServer
  TsgcWebSocketServer_HTTPAPI
 
When a HTTP client sends a multipart/form-data stream, the stream is saved by server in memory. When the files
are big, the server can get an out of memory exception, to avoid these exceptions, the server has a property
called HTTPUploadFiles where you can configure how the POST streams are handled: in memory or as a file
streams. If the streams are handled as file streams, the streams received are stored directly in the hard disk so the
memory problems are avoided.
 
To configure your server to save multipart/form-data streams as file streams, follow the next steps:
 
1. Set the property HTTPUploadFiles.StreamType = pstFileStream. Using this setup, the server will store these
streams in the hard disk.
2. You can configure which is the minimum size in bytes where the files will be stored as file stream. By default
the value is zero, which means all streams will be stored as file stream.
3. The folder where the streams are stored using SaveDirectory, if not set, will be stored in the same folder where
the application is.
4. When a client sends a multipart/form-data, the content is encoded inside boundaries, if the property Remove­
Boundaries is enabled, the content of boundaries will be extracted automatically after the full stream is received.
 
Sample Code
 
First create a new server instance and set the Streams are saved as File Streams.
 

oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 5555;
oServer.HTTPUploadFiles.StreamType := pstFileStream;
oServer.Active := True;

Then create a new html file with the following configuration


 
<html>
    <head><title>sgcWebSockets - Upload Big File</title></head>
    <body>
        <form  action="http://127.0.0.1:5555/file" method="post" enctype="multipart/
form-data">
            <input type="file" name="file_1" />
            <input type="submit" />
        </form>
    </body>
</html>
 
Finally open the html file with a web browser and send a file to the server. The server will create a new file stream
with the extension ".sgc_ps" and when the stream is fully received, it will extract the file from the boundaries.
 

Events
There are 2 events which can be used to customize the upload file flow (requires the property
HTTPUploadFiles.RemoveBoundaries is enabled)
 
OnHTTPUploadBeforeSaveFile
 
This event is fired BEFORE the file is saved and allows to customize the name of the file received.

81
TOPICS

procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; var aFileName: string; var aFilePath: string);


begin
  if aFileName = "test.jpg" then
    aFileName := "custom_test.jpg";
end;

OnHTTPUploadAfterSaveFile
 
This event is fired AFTER the file is saved and allows to know the name of the file saved.

procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; const aFileName: string; const aFilePath: string);


begin
  DoLog("File Received: " + aFileName);

end;

82
TOPICS

Compression
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketClient
  Web Browsers like Chrome
 
 
This is a feature that works very well when you need to send a lot of data, usually using a binary message, be­
cause it compresses WebSocket message using protocol "PerMessage_Deflate" which is supported by some
browsers like Chrome.
 
To enable this feature, you need to activate the following property:
 
  Extensions/ PerMessage_Deflate / Enabled
 
 
When a client tries to connect to a WebSocket Server and this property is enabled, it sends a header with this prop­
erty enabled, if Server has activated this feature, it sends a response to the client with this protocol activated and all
messages will be compressed, if Server doesn't have this feature, then all messages will be sent without compres­
sion.
 
On Web Browsers, you don't need to do anything, if this extension is supported it will be used automatically, if not,
then messages will be sent without compression.
 
If WebSocket messages are small, is better don't enable this property because it consumes cpu cycle to compress/
decompress messages, but if you are using a big amount of data, you will notify and increase on messages ex­
change speed.
 
 

83
TOPICS

Flash
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
 
WebSockets are supported natively by a wide range of web browsers (please check http://caniuse.com/websockets),
but there are some old versions that don't implement WebSockets (like Internet Explorer 6, 7, 8 or 9). You can en­
able Flash Fallback for all these browsers that don't implement WebSockets.
 
Almost all other or older browser support Flash installing Adobe Flash Player. To Support Flash connection, you
need to open port 843 on your server because Flash uses this port for security reasons to check for cross-domain-
access. If port 843 is not reachable, waits 3 seconds and tries to connect to Server default port.
 
Flash is only applied if the Browser doesn't support WebSockets natively. So, if you enable Flash Fallback on the
server side, and Web Browser supports WebSockets natively, it will still use WebSockets as transport.
 
To enable Flash Fallback, you need to access to FallBack / Flash property on the server and enable it. There are
2 properties more:
 
1. Domain: if you need to restrict flash connections to a single/multiple domains (by default all domains are al­
lowed). Example: This will allow access to domain swf.example.com
 
swf.example.com
 
 
2. Ports: if you need to restrict flash connections to a single/multiple ports (by default all ports are allowed). Exam­
ple: This will allow access to ports 123, 456, 457, and 458
 
123,456-458
 
 
Flash connections only support Text messages, binary messages are not supported.

84
TOPICS

Custom Objects
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketServer_HTTPAPI
  TsgcWebSocketClient
 
Every time a new WebSocket connection is established, sgcWebSockets creates a TsgcWSConnection class
where you can access to some properties like identifier, bytes received/sent, client IP... and there is a property
called Data where you can store objects in memory like database access, session objects...
 
 

//You can create a new class called MyClass and create some properties, example:
TMyClass = class
private
  FRegistered: Boolean;
  FUser: String;
public
  property Registered: Boolean read FRegistered write FRegistered;
  property User: String read FUser write FUser;
end;
 
// Then, when a new client connects, OnConnect Event, create a new TMyClass and Assign to Data:
procedure WSServerConnect(Connection: TsgcWSConnection);
begin
  Connection.Data := TMyClass.Create;
end;
 
// Every time a new message is received by the server, you can access your custom object
// using Connection.Data property.
procedure WSServerMessage(Connection: TsgcWSConnection; const Text: string);
begin
  if TMyClass(Connection.Data).Registered then
    DoSomeStuff();
end;
 
// When a connection is closed, you may free your object:
procedure TfrmServerChat.WSServerDisconnect(Connection: TsgcWSConnection; Code: Integer);
var
  oMyClass: TMyClass;
begin
  oMyClass := TMyClass(Connection.Data);
  if Assigned(oMyClass) then
  begin
    oMyClass.Free;
    Connection.Data := nil;
  end;
end;

85
TOPICS

IOCP
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
 
*Requires custom Indy version.
 
IOCP for Windows is an API which allows handles thousands of connections using a limited pool of threads instead
of using a thread for connection like Indy by default does.
To enable IOCP for Indy Servers, Go to IOHandlerOptions property and select iohIOCP as IOHandler Type.

Server.IOHandlerOptions.IOHandlerType := iohIOCP;
Server.IOHandlerOptions.IOCP.IOCPThreads := 8;
Server.IOHandlerOptions.IOCP.WorkOpThreads := 32;

 
IOCPThreads are the threads used for IOCP asynchronous requests (overlapped operations) and WorkOpThreads
are threads used to process these asynchronous requests (read and write bytes).
Maximum value of WorkOpThreads is 64, but you must adjust this value accordingly to your number of physical
processors * 2, so if you have a cpu with 16 processors, set a WorkOpThreads value of 32.
 
Enabling IOCP for windows servers is recommended when you need handle thousands of connections, if your
server is only handling 100 concurrent connections at maximum you can stay with default Indy Thread model.
 
 
OnDisconnect event not fired
 
IOCP works differently from default indy IOHandler. With default indy IOHandler, every connection runs in a thread
and these thread are running all the time and checking if connection is active, so if there is a disconnection, it's noti­
fied in a short period of time.
 
IOCP works differently, there is a thread pool which handles all connections, instead of 1 thread = 1 connection like
indy does by default. For IOCP, the only way to detect if a connection is still alive is trying to write in socket, if there
is any error means that connection is closed. There are 2 options to detect disconnections:
 
1. If you use TsgcWebSocketClient, you can enable it in Options property, CleanDisconnect := True (by default
is disabled). If it's enabled, before the client disconnects it sends a message informing the server about disconnec­
tion, so the server will receive this message and the OnDisconnect event will be raised.
2. You can enable heartbeat on the server side, for example every 60 seconds, so it will try to send a ping to all
clients connected and if there is any client disconnected, OnDisconnect will be called.

86
TOPICS

ALPN
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketClient
 
*Requires custom Indy version.
 
Application-Layer Protocol Negotiation (ALPN) is a Transport Layer Security (TLS) extension for application-layer
protocol negotiation. ALPN allows the application layer to negotiate which protocol should be performed over a se­
cure connection in a manner that avoids additional round trips and which is independent of the application-layer
protocols. It is needed by secure HTTP/2 connections, which improves the compresslion of web pages and reduces
their latency compared to HTTP/1.x.
 

Client
You can configure in TLSOptions.ALPNProtocols, which protocols are supported by client. When client connects to
server, these protocols are sent on the initial TLS handshake 'Client Hello', and it lists the protocols that the client
supports, and server select which protocol will be used, if any.
 
You can get which protocol has been selected by server accessing to ALPNProtocol property of TsgcWSConnec­
tionClient.
 

Server

When there is a new TLS connection, OnSSLALPNSelect event is called, here you can access to a list of protocols which are supported by client
and server can select which of them is supported.
 
 
If there is no support for any protocol, aProtocol can be left empty.
 

// Client
procedure OnClientConnect(Connection: TsgcWSConnection);
var
  vProtocol: string;
begin
  vProtocol := TsgcWSConnectionClient(Connection).ALPNProtocol;
end;
 
// Server
procedure OnSSLALPNSelect(Sender: TObject; aProtocols: TStringList; var aProtocol: string);
var
  i: integer;
begin
  for i := 0 to aProtocols.count - 1 do
  begin
    if aProtocols[i] = 'h2' then
    begin
      aProtocol := 'h2';
      break;
    end;
  end;
end;

87
TOPICS

Forward HTTP Requests


Supported by
 
  TsgcWebSocketHTTPServer
  TsgcWebSocketServer_HTTPAPI
  TsgcWSHTTPWebBrokerBridgeServer
  TsgcWSHTTP2WebBrokerBridgeServer
  TsgcWSServer_HTTPAPI_WebBrokerBridge
 
You can configure the server to forward some HTTP requests to another server, this is very useful when you have
more than one server and only one server is listening on a public address.
 
Example: you can configure your server, to forward to another server all requests to /internal while all other re­
quests are handled by sgcWebSockets server.
 
Use the event OnBeforeForwardHTTP to check if the URL requested must be forwarded and if it is, then set the
URL to forward.
 
Example: if you want to forward all requests to the document "/internal" to the server "localhost:8080", do the fol­
lowing:
 

procedure OnBeforeForwardHTTP(Connection: TsgcWSConnection; ARequestInfo: TIdHTTPRequestInfo;


  aForward: TsgcWSServerForwardHTTP);
begin
  if ARequestInfo.Document = '/internal' then
  begin
    aForward.Enabled := True;
    aForward.URL := 'http://localhost:8080';
  end;
end;

Other Options
When you want forward an HTTP request, you have the additional options:
 
1. By default, the request if forwarded using the original document. Example: if you forward the request http://local­
host:8080/internal to the internal server http://localhost:5555, the forwarded URL will be http://localhost:5555/inter­
nal. But you can modify the Document, using the Document property of Forward object (by default will use the
same of the original request).
 
aForward.Document = "/NewInternal"
 
2. If you forward a secure HTTP connection (HTTPs), you can customize the SSL/TLS options, in TLSOptions
property of Forward object. Example: set the TLS version
 
aForward.TLSOptions.Version = tls1_2

88
TOPICS

Quality Of Service
Supported by
 
  TsgcWSPServer_sgc
  TsgcWSPClient_sgc
  TsgcWSPClient_MQTT
  Java script
 
 
SGC Default Protocol and MQTT implements a QoS (Quality of Service) for message delivery, there are 3 different
types:
 
Level 0: "At most once", where messages are delivered according to the best efforts of the underlying TCP/
IP network. Message loss or duplication can occur. This level could be used, for example, with ambient sen­
sor data where it does not matter if an individual reading is lost as the next one will be published soon after.
 
Level 1: "At least once", where messages are assured to arrive but duplicates may occur.
 
Level 2: "Exactly once", where message are assured to arrive exactly once. This level could be used, for ex­
ample, with billing systems where duplicate or lost messages could lead to incorrect charges being applied.
 
 

Level 0

The message is delivered according to the best efforts of the underlying TCP/IP network. A response is not
expected and no retry semantics are defined in the protocol. The message arrives at the server either once
or not at all.
 
The table below shows the QoS level 0 protocol flow.
 
Client Message and direction Server

PUBLISH 
QoS = 0 Action: Publish a message to subscribers
---------->

Level 1

The receipt of a message by the server is acknowledged by a ACKNOWLEDGEMENT message. If there is


an identified failure of either the communications link or the sending device or the acknowledgement mes­
sage is not received after a specified period of time, the sender resends the message. The message arrives
at the server at least once.
 
A message with QoS level 1 has a Message ID in the message.
 
The table below shows the QoS level 1 protocol flow.
 
Client Message and direction Server

Actions:
QoS = 1 • Store message
PUBLISH 
Message ID = x • Publish a message to sub­
---------->
Action: Store message scribers
• Delete message

ACKNOWLEDGEMENT
Action: Discard message  
<----------
 

89
TOPICS

If the client does not receive an ACKNOWLEDGMENT message (either within a time period defined in the
application, or if a failure is detected and the communications session is restarted), the client may resend the
PUBLISH message.
 

Level 2

Additional protocol flows above QoS level 1 ensure that duplicate messages are not delivered to the receiv­
ing application. This is the highest level of delivery, for use when duplicate messages are not acceptable.
There is an increase in network traffic, but it is usually acceptable because of the importance of the message
content.
 
A message with QoS level 2 has a Message ID in the message.
 
The table below shows the QoS level 2 protocol flow. There are two semantics available for how a PUBLISH
flow should be handled by the recipient.
 
Client Message and direction Server

QoS = 2
PUBLISH 
Message ID = x Action: Store message
---------->
Action: Store message

PUBREC 
  Message ID = x
<----------

Actions:
PUBREL  • Publish a message to
Message ID = x
----------> subscribers
• Delete message

ACKNOWLEDGEMENT 
Action: Discard message Message ID = x
<----------
 
If a failure is detected, or after a defined time period, the protocol flow is retried from the last unacknowl­
edged protocol message. The additional protocol flows to ensure that the message is delivered to sub­
scribers once only.

 
 

90
TOPICS

Queues
Supported by
 
  TsgcWSPServer_sgc
  TsgcWSPClient_sgc
  Java script
 
 
 
SGC Default Protocol implements Queues to add persistence to published messages (it's only available for Pub­
lished messages)
 
Level 0: Messages are not queued on Server
 
Level 1: only last message is queued on Server, and is sent every time a client subscribes to a new channel
or connects to the server.
 
Level 2: All messages are queued on Server, and are sent every time a client subscribes to a new channel
or connects to the server.
 
 

Level 0

The message is not queued by Server


 
The table below shows the Queue level 0 protocol flow.
 
Client Message and direction Server

PUBLISH 
Queue = 0 Action: Publish a message to subscribers
---------->

Level 1

 
A message with Queue level 1 is stored on the server and if there are other messages stored for this chan­
nel, are deleted.
 
The table below shows the Queue level 1 protocol flow.
 
Client Message and direction Server

Actions:
PUBLISH 
Queue = 1 • Deletes All messages of this channel
---------->
• Store last message by Channel

Action: Process NOTIFY Action: Every time a new client subscribes to


message <---------- this channel, the last message is sent.
 
This is useful where publishers send messages on a "report by exception" basis, where it might be some
time between messages. This allows new subscribers to instantly receive data with the retained, or Last Known
Good, value.
 

Level 2

91
TOPICS

All messages with Queue level 2 are stored on the server.


 
The table below shows the Queue level 2 protocol flow.
 
Client Message and direction Server

PUBLISH 
Queue = 2 Action: Store message
---------->

Action: Process NOTIFY Action: Every time a new client subscribes to


message <---------- this channel, ALL Messages are sent.
 
 

92
TOPICS

Transactions
Supported by
 
  TsgcWSPServer_sgc
  TsgcWSPClient_sgc
  Java script
 
sgcWebSockets SGC Protocol supports transactional messaging, when a client commits a transaction, all mes­
sages sent by the client are processed on the server side. There are 3 methods called by the client:
 
StartTransaction
 
  Creates a New Transaction on the server side and all messages that are sent from the client to the server after
this method, are queued on Server side, until the client calls to Commit or Rollback
 
Message and di­
Client Server
rection

STARTTRANSAC­
Action: Creates a new Queue to store all Mes­
Channel = X TION
sages of the specified channel
---------->

PUBLISH
Channel = X Action: Message is stored on Server Side.
---------->

Action: Client get  ACKNOWLEDGE­
Action: Server returns an Acknowledgement to 
confirmation of MENT
the client because message is stored.
message sent <----------

.... .... ....


 
 
Commit
  
  When a client calls to commit, all messages queued by the server are processed.
 
Client Message and direction Server

Channel = COMMIT Action: Process all messages queued by Transac­


X ----------> tion
 
 
 
RollBack
 
  When a client calls to RollBack, all messages queued by the server are deleted and not processed on the server
side.
 
Client Message and direction Server

ROLLBACK
Channel = X Action: Delete all messages queued by Transaction
---------->
 

93
TOPICS

TCP Connections
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketServer_HTTPAPI
  TsgcWebSocketClient
 
By default, sgcWebSocket use WebSocket as protocol, but you can use plain TCP protocol in client and server
components.
 
Client Component
Disable WebSocket protocol.

Client.Specifications.RFC6455 := False;
 

 
Server Component
Handle event OnUnknownProtocol and set Transport as trpTCP and Accept the connection.

procedure OnUnknownProtocol(Connection: TsgcWSConnection;  var Accept: Boolean);


begin
  Connection.Transport := trpTCP;
  Accept := True;
end;

 
Then when a client connects to the server, this connection will be defined as TCP and will use plain TCP protocol
instead of WebSockets. Plain TCP connections don't know if the message is text or binary, so all messages re­
ceived are handle OnBinary event.
 
End of Message
If messages are big, sometimes can be received fragmented. There is a method to try to find end of message set­
ting which bytes find. Example: STOMP protocol, all messages ends with byte 0 and 10

procedure OnWSClientConnect(Connection: TsgcWSConnection);


begin
  Connection.TCPEndOfFrameScanBuffer := eofScanAllBytes;
  Connection.AddTCPEndOfFrame(0);
  Connection.AddTCPEndOfFrame(10);
end;

94
TOPICS

SubProtocol
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketClient
  TsgcWebSocketServer_HTTPAPI
 
WebSocket provides a simple subprotocol negotiation, basically adds a header with protocols name supported by
request, these protocols are received and if the receiver supports one of them, sends a response with subprotocol
supported.
 
sgcWebSockets supports several SubProtocols: MQTT, WAMP... and more. You can implement your own subpro­
tocols using a very easy method, just call RegisterProtocol and send SubProtocol Name as an argument.
 
Example: you need to connect to a server which implements subprotocol "Test 1.0"
 

Client := TsgcWebSocketClient.Create(nil);
Client.Host := 'server host';
Client.Port := server.port;
Client.RegisterProtocol('Test 1.0');
Client.Active := True;

95
TOPICS

Throttle
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketClient
 
Bandwidth Throttling is supported by Server and Client components, if enabled, can limit the number of bits per
second sent/received by the socket. Indy uses a blocking method, so if a client is limiting its reading, unread data
will be inside the client socket and the server will be blocked from writing new data to the client. As much slower is
client reading data, much slower is server writing new data.
 
 

96
TOPICS

Server-sent Events (Push Notifications)


Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  Java script
 
SSE are not part of WebSockets, defines an API for opening an HTTP connection for receiving push notifications
from a server.
 
SSEs are sent over traditional HTTP. That means they do not require a special protocol or server implementation to
get working. In addition, Server-Sent Events have a variety of features that WebSockets lack by design such as au­
tomatic reconnection, event IDs, and the ability to send arbitrary events.
 
Events
 
• Open: when a new SSE connection is opened.
• Message: when the client receives a new message.
• Error: when there any connection error like a disconnection.
 
 
JavaScript API
 
To subscribe to an event stream, create an EventSource object and pass it the URL of your stream:
 

var sse = new EventSource('sse.html');


 
sse.addEventListener('message', function(e)
 {console.log(e.data);
}, false);
 
sse.addEventListener('open', function(e) {
  // Connection was opened.
}, false);
 
sse.addEventListener('error', function(e) {
  if (e.readyState == EventSource.CLOSED) {
    // Connection was closed.
  }
}, false);

 
 
When updates are pushed from the server, the onmessage handler fires and new data is available in its e.data
property. If the connection is closed, the browser will automatically reconnect to the source after ~3 seconds (this is
a default retry interval, you can change on the server side).
 
 
Fields
 
The following field names are defined by the specification:
 
event
 
The event's type. If this is specified, an event will be dispatched on the browser to the listener for the specified
event name; the web site would use addEventListener() to listen for named events. the onmessage handler is
called if no event name is specified for a message.
 
 
data
 

97
TOPICS

The data field for the message. When the EventSource receives multiple consecutive lines that begin with data:, it
will concatenate them, inserting a newline character between each one. Trailing newlines are removed.
 
 
id
 
The event ID to set the EventSource object's last event ID value to.
 
 
retry
 
The reconnection time to use when attempting to send the event. This must be an integer, specifying the reconnec­
tion time in milliseconds. If a non-integer value is specified, the field is ignored.
 
All other field names are ignored.
 
 
For multi-line strings use #10 as line feed.
 
 
Examples of use:
 
If you need to send a message to a client, just use WriteData method.
 

// If you need to send a message to a client, just use WriteData method.


Connection.WriteData('Notification from server');
  
// To send a message to all Clients, use Broadcast method.
Connection.Broadcast('Notification from server');
  
// To send a message to all Clients, use Broadcast method.
Connection.Broadcast('Notification from server');
  
// To send a message to all Clients using url 'sse.html', use Broadcast method and Channel parameter:
Connection.Broadcast('Notification from server', '/sse.html');
  
// You can send a unique id with an stream event by including a line starting with "id:":
Connection.WriteData('id: 1' + #10 + 'data: Notification from server');
  
// If you need to specify an event name:
Connection.WriteData('event: notifications' + #10 + 'data: Notification from server');

 
 
 
javascript code to listen "notifications" channel:
 

   sse.addEventListener('notifications',      function(e) {
      console.log('notifications:'  + e.data);
   },  false);

 
 
 
 

98
TOPICS

LoadBalancing
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketLoadBalancerServer
 
 
Load Balancing allows distributing work between several back-end servers, every time a new client requests a con­
nection, it connects to a load balancer server (which is connected to back-end servers) and returns a connection
string with information about the host, port... which is used by the client to connect to a server. If you have for ex­
ample 4 servers, with this method all servers will have, more or less, the same number of connections, and work­
load will be similar.
 
If a client wants to send a message to all clients of all servers, just use broadcast method, and this message will be
broadcast to all servers connected to Load Balancer Server.
 
To enable this feature:
 
1. Drop a TsgcWebSocketLoadBalancerServer component, set a listening port and set active to True.
 
2. Server and Client components, have a property called LoadBalancer, where you need to set host and port
of Load Balancer Server, and enabled True.
 

99
TOPICS

Files
Supported by
 
  TsgcWSPServer_sgc
  TsgcWSPClient_sgc
 
This protocol allows sending files from client to server and from server to client in an easy way. You can send from
really small files to big files using a low memory usage. You can set:
 
1. Packet size in bytes.
2. Use custom channels to send files to only subscribed clients.
3. The progress of file send and received.
4. Authorization of files received.
5. Acknowledgement of packets sent.
 

100
TOPICS

Proxy
Supported by
 
  TsgcWebSocketClient
 
Client WebSocket components support WebSocket connections through HTTP proxies, to enable proxy connection
you need to activate the following properties:
 
Proxy / Enabled
 
Once set to True, you can set up:
 
Host: Proxy server address
Port: Proxy server port
UserName/Password: Authentication to connect to proxy, only if required.
 
You can configure SOCKS proxies accessing to SOCKS property and set Enable to True.

101
TOPICS

Fragmented Messages
Supported by
 
  TsgcWebSocketServer
  TsgcWebSocketHTTPServer
  TsgcWebSocketClient
  TsgcWebSocketServer_HTTPAPI
 
By default, when a stream is sent using sgcWebSockets library, it sends all data in a single packet or buffers all
packets and when the latest packet is received, OnBinary message event is called.
This behaviour can be customized by Options.FragmentedMessages property, which accepts following values:
 
1. frgOnlyBuffer: this is the default value, means that packet messages will be buffered and only when all stream is
received, OnBinary message will be called.
2. frgOnlyFragmented: this means that OnFragmented event only will be called for every packet received.
3. frgAll: this means that OnFragmented event will be called for every packet received and when the full stream is
received.
 
OnFragmented event is useful when you must send big streams and receiver must show progress of the transfer.
 
Example: the client must send a stream of size 1.000.000 bytes to server and server wants show progress for
every 1000 bytes received
 
 
The client will send a stream using writedata method with a size for a packet of 1000

Client.WriteData(stream, 1000);

The server will set in Options.FragmentedMessages := frgAll and will handle OnFragmented event to receive
progress of streams

procedure OnFragmented(Connection: TsgcWSConnection;  const Data: TMemoryStream; const OpCode: TOpcode; const Continuation:


begin
  ShowProgress(Data.Size);
  if not Continuation then
    SaveStream(Data);
end;

102
COMPONENTS

TsgcWebSocketClient
TsgcWebSocketClient implements Client WebSocket Component and can connect to a WebSocket Server. Follow
the next steps to configure this component:
 
1. Drop a TsgcWebSocketClient component onto the form
 
2. Set Host and Port (default is 80) to connect to an available WebSocket Server. You can set URL property and
Host, Port, Parameters... will be updated from URL. Example: wss://127.0.0.1:8080/ws/ will result:

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClient.TLS := True;
oClient.Options.Parameters := '/ws/';

3. You can select if you require TLS (secure connection) or not, by default is not Activated.
 
4. You can connect through an HTTP Proxy Server, you need to define proxy properties:
 
    Host: hostname of the proxy server.
    Port: port number of the proxy server.
    Username: user to authenticate, blank if anonymous.
    Password: password to authenticate, blank if anonymous.
 
5. If the server supports compression, you can enable compression to compress messages sent.
 
6. Set Specifications allowed, by default all specifications are allowed.
 
    RFC6455: is standard and recommended WebSocket specification.
 
    HIxie76: always is false
 
7. If you want, you can handle events
 
    OnConnect: when a WebSocket connection is established, this event is fired
 
    OnDisconnect: when a WebSocket connection is dropped, this event is fired
 
    OnError: every time there is a WebSocket error (like mal-formed handshake), this event is fired
 
    OnMessage: every time the server sends a text message, this event is fired
 
    OnBinary: every time the server sends a binary message, this event is fired
 
    OnFragmented: when receives a fragment from a message (only fired when Options.FragmentedMessages =
frgAll or frgOnlyFragmented).
 
    OnHandhake: this event is fired when handshake is evaluated on the client side.
 
    OnException: every time an exception occurs, this event is fired.
 
    OnSSLVerifyPeer: if verify certificate is enabled, in this event you can verify if server certificate is valid and ac­
cept or not.
 
    OnBeforeHeartBeat: if HeartBeat is enabled, allows to implement a custom HeartBeat setting Handled parame­
ter to True (this means, standard websocket ping won't be sent).
 
    OnBeforeConnect: before the client tries to connect to server, this event is called.
 

103
COMPONENTS

    OnBeforeWatchDog: if WatchDog is enabled, allows to implement a custom WatchDog setting Handled para­
meter to True (this means, won't try to connect to server). You can change the Server Connection properties too
before try to reconnect, example: connect to a fallback server if first fails.
 
 
8. Set property Active = true to start a new websocket connection
 
 

Most common uses


• Connection
• How Connect WebSocket Server
• Open a Client Connection
• Close a Client Connection
• Keep Connection active
• Dropped Disconnections
• Connect TCP Server
• WebSocket Redirections
 
• Secure Servers
• Connect Secure Server
• Certificates OpenSSL
• Certificates SChannel
• SChannel Get Connection Info
 
• Send Messages
• Send Text Message
• Send Binary Message
 
• Receive Messages
• Receive Text Messages
• Receive Binary Messages
 
• Authentication
• Client Authentication
 
• Other
• Client Exceptions
• Client WebSocket HandShake
• Client Register Protocol
• Client Proxies
 

Methods
 
    WriteData: sends a message to a WebSocket Server. Could be a String or MemoryStream. If "size" is set, the
packet will be split if the size of the message is greater of size.
 
    Ping: sends a ping to a Server. If a time-out is specified, it waits for a response until a time-out is exceeded, if no
response, then closes the connection.
 
    Start: uses a secondary thread to connect to the server, this prevents your application freezes while trying to
connect.
 
    Stop: uses a secondary thread to disconnect from the server, this prevents your application freezes while trying
to disconnect.
 
    Connect: try to connect to the server and wait till the connection is successful or there is an error.
 
    Disconnect: try to disconnect from the server and wait till disconnection is successful or there is an error.
 
 

104
COMPONENTS

Properties
    Authentication: if enabled, WebSocket connection will try to authenticate passing a username and password.
      
       Implements 4 types of WebSocket Authentication
 
Session: client needs to do a HTTP GET passing username and password, and if authenticated, server re­
sponse a Session ID. With this Session ID, client open WebSocket connection passing as a parameter.
 
URL: client open WebSocket connection passing username and password as a parameter.
 
Basic: uses basic authentication where user and password as sent as HTTP Header.
 
Token: sends a token as HTTP Header. Usually used for bearer tokens where token must be set in AuthTo­
ken property.
 
• OAuth: if a OAuth2 component is attached, before client connects to server, it requests a new Access
Token to Authorization server. OAuth2 Component.
 
    Host: IP or DNS name of the server.
 
     HeartBeat: if enabled try to keeps alive WebSocket connection sending a ping every x seconds.
 
Interval: number of seconds between each ping.
 
Timeout: max number of seconds between a ping and pong.
 
     TCPKeepAlive: if enabled, uses keep-alive at TCP socket level, in Windows will enable
SIO_KEEPALIVE_VALS if supported and if not will use keepalive. By default is disabled. Read about Dropped Dis­
connections.
 
Time: if after X time socket doesn't sends anything, it will send a packet to keep-alive connection (value in
milliseconds).
 
Interval: after sends a keep-alive packet, if not received a response after interval, it will send another packet
(value in milliseconds).
 
    ConnectTimeout: max time in milliseconds before a connection is ready.
 
  LoadBalancer: it's a client which connects to Load Balancer Server to broadcast messages and get information
about servers.
 
Enabled: if enabled, it will connect to Load Balancer Server.
 
Host: Load Balancer Server Host.
 
Port: Load Balancer Server Port.
 
      Servers: here you can set manual WebSocket Servers to connect (if you don't make use of Load Balancer
Server get server connection methods), example:
 
http://127.0.0.1:80
http://127.0.0.2:8888
 
    Connected: returns true if the connection is active. Use this property carefully, because uses internal "connect­
ed" Indy method, and this method may lock the thread and/or increment the use of cpu. If you want to know if the
client is connected, just use the Active property, which is safer.
 
    ReadTimeout: max time in milliseconds to read messages.
 
    WriteTimeOut: max time in milliseconds sending data to other peer, 0 by default (only works under Windows
OS).
 
    BoundPortMin: minimum local port used by client, by default zero (means there aren't limits).
 

105
COMPONENTS

    BoundPortMax: max local port used by client, by default zero (means there aren't limits).
 
    Port: Port used to connect to the host.
 
     LogFile: if enabled save socket messages to a specified log file, useful for debugging. The access to log file is
not thread safe if it's accessed from several threads.
 
Enabled: if enabled every time a message is received and sent by socket it will be saved on a file.
 
FileName: full path to the filename.
 
UnMaskFrames: by default True, means that saves the websocket messages sent unmasked.
 
    NotifyEvents: defines which mode to notify WebSocket events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 
    Options: allows customizing headers sent on the handshake.
 
FragmentedMessages: allows handling Fragmented Messages
 
           frgOnlyBuffer: the message is buffered until all data is received, it raises OnBinary or OnMessage
event (option by default)
           frgOnlyFragmented: every time a new fragment is received, it raises OnFragmented Event.
           frgAll: every time a new fragment is received, it raises OnFragmented Event with All data received
from the first packet. When all data is received, it raises OnBinary or OnMessage event.
 
Parameters: define parameters used on GET.
 
Origin: customize connection origin.
 
RaiseDisconnectExceptions: enabled by default, raises an exception every time there is a disconnection
by protocol error.
 
ValidateUTF8: if enabled, validates if the message contains UTF8 valid characters, by default is disabled.
 
CleanDisconnect: if enabled, every time client disconnects from server, first sends a message to inform
server connection will be closed.
 
    QueueOptions: this property allows to queue the messages in an internal queue (instead of send directly) and
send the messages in the context of the connection thread, this prevents locks when several threads try to send a
message. For every message type: Text, Binary or Ping a queue can be configured, by default the value set is qm­
None which means the messages are not queued. The other types, means different queue levels and the differ­
ence between them are just the order where are processed (first are processed qmLevel1, then qmLevel2 and fi­
nally qmLevel3).
Example: if Text and Binary messages have the property set to qmLevel2 and Ping to qmLevel1. The client will
process first the Ping messages (so the ping message is sent first than Text or Binary if they are queued at the
same time), and then process the Text and Binary messages in the same queue.
 
    Extensions: you can enable compression on messages sent.
 
    Protocol: if exists, shows the current protocol used
 
    Proxy: here you can define if you want to connect through a Proxy Server, you can connect to the following
proxy servers:
pxyHTTP: HTTP Proxy Server.
pxySocks4: SOCKS4 Proxy Server.
pxySocks4A: SOCKS4A Proxy Server.

106
COMPONENTS

pxySocks5: SOCKS5 Proxy Server.


 
    WatchDog: if enabled, when an unexpected disconnection is detected, tries to reconnect to the server automati­
cally.
 
Interval: seconds before reconnects.
 
Attempts: max number of reconnects, if zero, then unlimited.
 
    Throttle: used to limit the number of bits per second sent/received.
 
    TLS: enables a secure connection.
 
    TLSOptions: if TLS enabled, here you can customize some TLS properties.
 
ALPNProtocols: list of the ALPN protocols which will be sent to server.
RootCertFile: path to root certificate file.
CertFile: path to certificate file.
KeyFile: path to certificate key file.
Password: if certificate is secured with a password, set here.
VerifyCertificate: if certificate must be verified, enable this property.
VerifyDepth: is an Integer property that represents the maximum number of links permitted when verifica­
tion is performed for the X.509 certificate.
Version: by default negotiates all possible TLS versions from newer to lower. A specific TLS version can be
selected.
tlsUndefined: this is the default value, the client will try to negotiate all possible TLS versions (start­
ing from newest to oldest), till connects successfully.
tls1_0: implements TLS 1.0
tls1_1:implements TLS 1.1
tls1_2: implements TLS 1.2
tls1_3: implements TLS 1.3
IOHandler: select which library you will use to connection using TLS.
iohOpenSSL: uses OpenSSL library and is the default for Indy components. Requires to deploy
openssl libraries (can be download from the private account of registered customers).
iohSChannel: uses Secure Channel which is a security protocol implemented by Microsoft for Win­
dows, doesn't require to deploy openssl libraries. Only works in Windows 32/64 bits.
OpenSSL_Options: configuration of the openSSL libraries.
APIVersion: allows to define which OpenSSL API will be used.
oslAPI_1_0: uses API 1.0 OpenSSL, it's latest supported by Indy
oslAPI_1_1: uses API 1.1 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 1.1.1 libraries (with TLS 1.3 support).
oslAPI_3_0: uses API 3.0 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 3.0.0 libraries (with TLS 1.3 support).
LibPath: here you can configure where are located the openSSL libraries
oslpNone: this is the default, the openSSL libraries should be in the same folder where is the
binary or in a known path.
oslpDefaultFolder: sets automatically the openSSL path where the libraries should be located
for all IDE personalities.
oslpCustomFolder: if this is the option selected, define the full path in the property LibPath­
Custom.
LibPathCustom: when LibPath = oslpCustomFolder define here the full path where are located the
openSSL libraries.
UnixSymLinks: enable or disable the loading of SymLinks under Unix systems (by default is en­
abled, except under OSX64):
oslsSymLinksDefault: by default are enabled except under OSX64 (after MacOS Monterey
fails trying to load the library without version.).
oslsSymLinksLoadFirst: Load SymLinks and do before trying to load the version libraries.
oslsSymLinksLoad: Load SymLinks after trying to load the version libraries.
oslsSymLinksDontLoad: don't load the SymLinks.
SChannel_Options: allows to use a certificate from Windows Certificate Store.
CertHash: is the certificate Hash. You can find the certificate Hash running a dir command in power­
shell.
CipherList: here you can set which Ciphers will be used (separated by ":"). Example:
CALG_AES_256:CALG_AES_128
CertStoreName: the store name where is stored the certificate. Select one of below:

107
COMPONENTS

scsnMY (the default)


scsnCA
scsnRoot
scsnTrust
CertStorePath: the store path where is stored the certificate. Select one of below:
scspStoreCurrentUser (the default)
scspStoreLocalMachine
 
 
 
 

108
COMPONENTS

TsgcWebSocketClient | Connect WebSocket


Server
URL Property
The most easy way to connect to a WebSocket server is use URL property and call Active = true.
 
Example: connect to echo.websocket.org using secure connection.

oClient := TsgcWebSocketClient.Create(nil);
oClient.URL := 'wss://echo.websocket.org';
oClient.Active := true;

Host, Port and Parameters


You can connect to a WebSocket server using Host and port properties.
 
Example: connect to echo.websocket.org using secure connections

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := 'echo.websocket.org';
oClient.Port := 443;
oClient.TLS := true;
oClient.Active := true;

109
COMPONENTS

TsgcWebSocketClient | Client Open Connec­
tion
Once your client is configured to connect to server, there are 3 different options to call Open a new connection.
 

Active Property
The most easy way to open a new connection is Set Active property to true. This will try to connect to server using
component configuration.
If you set Active property to false, will close connection if active.
This method is executed in the same thread that caller. So if you call in the Main Thread, method will be executed
in Main Thread of application.
 
Open Connection

oClient := TsgcWebSocketClient.Create(nil);
...
oClient.Active := true;

When you call Active = true, you can't still send any data to server because client maybe is still connecting, you
must first wait to OnConnect event is fired and then you can start to send messages to server.
 
 
Close Connection

oClient.Active := false;

When you call Active = false, you cannot be sure that connection is already closed just after this code, so you
must wait to OnDisconnect event is fired.
 
 

Start/Stop methods
When you call Start() or Stop() to connect/disconnect from server, is executed in a secondary thread, so it doesn't
blocks the thread where is called. Use this method if you want connect to a server and let your code below contin­
ue.
 
Open Connection

oClient := TsgcWebSocketClient.Create(nil);
...
oClient.Start();

When you call Start(), you can't still send any data to server because client maybe is still connecting, you must
first wait to OnConnect event is fired and then you can start to send messages to server.
 
Close Connection

oClient.Stop();

When you call Stop(), you cannot be sure that connection is already closed just after this code, so you must
wait to OnDisconnect event is fired.
 
 

110
COMPONENTS

Connect/Disconnect methods
When you call Connect() or Disconnect() to open/close connection from server, this is executed in the same thread
where is called, but it waits till process is finished. You must set a Timeout to set the maximum time to wait till
process is finished (by default 10 seconds)
 
Example: connect to server and wait till 5 seconds

oClient := TsgcWebSocketClient.Create(nil);
...
if oClient.Connect(5000) then
  oClient.WriteData('Hello from client')
else
  Error();

If after calling Connect() method, the result is successful, you can already send a message to server because con­
nection is alive.
 
 
Example: connect to server and wait till 10 seconds

if oClient.Disconnect(10000) then
  ShowMessage('Disconnected')
else
  ShowMessage('Not Disconnected');

If after calling Disconnect() event the result is successful, this means that connection is already closed.
 
OnBeforeConnect event can be used to customize the server connection properties before the client tries to con­
nect to it.

111
COMPONENTS

TsgcWebSocketClient | Client Close Con­
nection
Connection can be closed using Active property, Stop or Disconnect methods, read more from Client Open Con­
nection.
 

CleanDisconnect
When connection is closed, you can notify other peer that connection is closed sending a message about close
connection, to enable this feature, Set Options.CleanDisconnect property to true.
If this property is enabled, before connection is closed, a Close message will be sent to server to notify that client is
closing connection.
 

Disconnect
TsgcWSConnection has a method called Disconnect(), that allows to disconnect connection at socket level. If you
call this method, socket will be disconnected directly without waiting any response from server. You can send a
Close Code with this method.
 

Close
TsgcWSConnection has a method called Close(), which allows to send a message to server requesting to close
connection, if server receives this message, must close the connection and client will receive a notification that con­
nection is closed. You can send a Close Code with this method.

112
COMPONENTS

TsgcWebSocketClient |Client Keep Connec­
tion Open
Once your client has connected to server, sometimes connection can be closed due to poor signal, connection er­
rors... there are 2 properties which helps to keep connection active.
 

HeartBeat
HeartBeat property allows to send a Ping every X seconds to maintain connection alive. Some servers, close
TCP connections if there is no data exchanged between peers. HeartBeat solves this problem, sending a ping
every a specific interval. Usually this is enough to maintain a connection active, but you can set a TimeOut interval
if you want to close connection if a response from server is not received after X seconds.
 
Example: send a ping every 30 seconds

oClient := TsgcWebSocketClient.Create(nil);
oClient.HeartBeat.Interval := 30;
oClient.HeartBeat.Timeout := 0;
oClient.HeartBeat.Enabled := true;
oClient.Active := true;

There is an event called OnBeforeHeartBeat which allows to customize HeartBeat behaviour. By default, if Heart­
Beat is enabled, client will send a websocket ping every X seconds set by HeartBeat.Interval property.
OnBeforeHeartBeat has a parameter called Handled, by default is false, which means the flow is controlled by Ts­
gcWebSocketClient component. If you set the value to True, then ping won't be sent, and you can send your cus­
tom message using Connection class.

WatchDog
If WatchDog is enabled, when client detects a disconnection, WatchDog try to reconnect again every X seconds
until connection is active again.
 
Example: reconnect every 10 seconds after a disconnection with unlimited attempts.
 

oClient := TsgcWebSocketClient.Create(nil);
oClient.WatchDog.Interval := 10;
oClient.WatchDog.Attempts := 0;
oClient.WatchDog.Enabled := true;
oClient.Active := true;

You can use OnBeforeWatchDog event to change the Server where the client will try to connect. Example: after 3
retries, if the client cannot connect to a server, will try to connect to a secondary server.
The Handled property, if set to True, means that the client won't try to reconnect.

113
COMPONENTS

TsgcWebSocketClient | Dropped Disconnec­
tions
Once the connection has been established, if no peer sends any data, then no packets are sent over the net. TCP
is an idle protocol, so it assumes that the connection is active.

Disconnection reasons
• Application closes: when a process is finished, usually sends a FIN packet which acknowledges the other
peer that connection has been closed. But if a process crashes there is no guarantee that this packet will be
sent to other peer.
• Device Closes: if devices closes, most probably there won't be any notification about this.
• Network cable unplugged: if network cable is unplugged it's the same that a router closes, there is no data
being transferred so connection is not closed.
• Loss signal from router: if application loses signal from router, connection will still be alive.
 

Detect Half-Open Disconnections


You can try to detect disconnections using the following methods

Second Connection

You can try to open a second connection and try to connect but this has some disadvantages, like you are consum­
ing more resources, create new threads... and if other peer has rebooted, second connection will work but first
won't.

Ping other peer

If you try to send a ping or whatever message with a half-open connection, you will see that you don't get any error.
 

Enable KeepAlive at TCP Socket level

A TCP keep-alive packet is simply an ACK with the sequence number set to one less than the current sequence
number for the connection. A host receiving one of these ACKs responds with an ACK for the current sequence
number. Keep-alives can be used to verify that the computer at the remote end of a connection is still available.
TCP keep-alives can be sent once every TCPKeepAlive.Time (defaults to 7,200,000 milliseconds or two hours) if
no other data or higher-level keep-alives have been carried over the TCP connection. If there is no response to a
keep-alive, it is repeated once every TCPKeepAlive.Interval seconds. KeepAliveInterval defaults to 1000 millisec­
onds.
 
You can enable per-connection KeepAlive and allow that TCP protocol check if connection is active or not. This is
the preferred method if you want to detect dropped disconnections (for example: when you unplug a network ca­
ble).
 

oClient := TsgcWebSocketClient.Create(nil);
oClient.TCPKeepAlive.Enabled := True;
oClient.TCPKeepAlive.Time := 5000;
oClient.TCPKeepAlive.Interval := 1000;

114
COMPONENTS

TsgcWebSocketClient | Connect TCP Server


TsgcWebSocketClient can connect to WebSocket servers but can connect to plain TCP Servers too.

URL Property
The most easy way to connect to a WebSocket server is use URL property and call Active = true.
 
Example: connect to 127.0.0.1 port 5555

oClient := TsgcWebSocketClient.Create(nil);
oClient.URL := 'tcp://127.0.0.1:5555';
oClient.Active := true;

Host, Port and Parameters


You can connect to a TCP server using Host and port properties.
 
Example: connect to 127.0.0.1 port 5555

oClient := TsgcWebSocketClient.Create(nil);
oClient.Specifications.RFC6455 := false;
oClient.Host := '127.0.0.1';
oClient.Port := 5555;
oClient.Active := true;

115
COMPONENTS

TsgcWebSocketClient | Connections
TIME_WAIT
When a client initiates a disconnection from server, there is an exchange between client and server to inform about
the state of disconnection. When the process is finished, the client socket connection states as TIME_WAIT during
a variable time. This is a normal behavior, in windows operating systems, this time defaults to about 4 minutes.
 
You can reduce or eliminate this behaviour, do with careful, using the following alternatives.
 
REGEDIT
 
You can reduce the TIME_WAIT value using the Windows Regedit
 
1. Open Regedit and access to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
Services\TCPIP\Parameters registry subkeys.
2. Create a new REG_DWORD value named TcpTimedWaitDelay
3. Set the value in Seconds. Example: if you set a value of 5, means that TIME_WAIT will waits as max as 5 sec­
onds.
4. Save and restart the system.
 
 
LINGER
 
Another option to avoid TIME_WAIT state, is use the socket option SO_LINGER, if enabled, instead of closing the
connection gracefully, the client resets the connection so the TIME_WAIT state is avoided.
You can enable this option using LingerState property, by default has a value of -1. If you set a value of zero, the
connection will be reset when disconnecting from socket without Timeout.
This options is probably the less recommended and only use as a last option.

116
COMPONENTS

TsgcWebSocketClient | WebSocket Redirec­
tions
When the client connects to a WebSocket server, the server can return an HTTP Response Code 30x. If the Re­
sponse code it's a 301, means that the location has been moved permanently, and the new url is informed in the
Location HTTP Header.
 
The WebSocket client, handle redirections automatically, so if detects the Server Response contains a redirection,
it will disconnect the actual connection and try to connect with then new Location URL.
 

Example
1. Client first tries to connect to url ws://127.0.0.1:5000
2. Server returns a Response Code of 301 and contains a Header Location with the value ws://80.50.1.2:3000
3. Client reads the Response from server, detects that it's a redirection and reads the Location
1. First Disconnects the actual connection.
2. Update the URL property with the value of Location Header (ws://80.50.1.2:3000)
3. Connects to the new server.

117
COMPONENTS

TsgcWebSocketClient | Connect Secure


Server
TsgcWebSocketClient can connect to WebSocket servers using secure and none-secure connections.

You can configure a secure connection, using URL property or Host / Port properties, see Connect to WebSocket
Server.

TLSOptions
In TLSOptions property there are the properties to customize a secure connection. The most important property
is version, which specifies the version of TLS protocol. Usually setting TLS property to true and
TLSOptions.Version to tlsUndefined is enough for the wide majority of WebSocket Servers.
 
TLSOptions.Version allows to set the TLS version used to connect to server or let the client negotiate the TLS ver­
sion from all available (this is the default when value is tlsUndefined).
 
If you get an error trying to connect to a server about TLS protocol, most probably this server requires a TLS
version newer than you set.
 
If TLSOptions.IOHandler is set to iohOpenSSL, you need to deploy OpenSSL libraries (which are the libraries
that handle all TLS stuff), check the following article about OpenSSL.
If TLSOptions.IOHandler is set to iohSChannel, then there is no need to deploy any library (only windows is
supported).

118
COMPONENTS

TsgcWebSocketClient | Certificates
OpenSSL
When the server requires that client connects using a SSL Certificate, use the TLSOptions property of TsgcWeb­
SocketClient to set the certificate files. The certificate must be in PEM format, so if the certificate has a different for­
mat, first must be converted to PEM.
 
Connection through OpenSSL libraries requires that TLSOptions.IOHandler = iohOpenSSL.
 
Configure the following properties:
 
• CertFile: is the path to the certificate in PEM format.
• KeyFile: is the path to the private key of the certificate.
• RootCertFile: is the path to the root of the certificate.
• Password: if certificate is protected by a password, set here the secret.

119
COMPONENTS

TsgcWebSocketClient | Certificates SChan­
nel
When the server requires that client connects using a SSL Certificate, use the TLSOptions property of TsgcWeb­
SocketClient to set the certificate files.
 
Connection through SChannel requires that TLSOptions.IOHandler = iohSChannel.
 
SChannel support 2 types of certificate authentication:
 
1. Using a PFX certificate
2. Setting the Hash Certificate of an already installed certificate in the windows system.
 

PFX Certificate
PFX Certificate is a file that contains the certificate and private key, sometimes you have a certificate in PEM for­
mat, so before use it, you must convert to PFX.
Use the following openssl command to converte a PEM certificate to PFX
 

openssl pkcs12 -inkey certificate-pem.key -in certificate-pem.crt -export -out certificate.pfx

Once the certificate has PFX format, you only need to deploy the certificate and set in the TLSOptions.Certificate
property the path to it.
 

TLSOptions.IOHandler = iohSChannel
TLSOptions.CertFile = <certificate path>
TLSOptions.Password = <certificate optional password>

Hash Certificate
If the certificate is already installed in the windows certificate store, you only need to know the certificate thumbprint
and set in the TLSOptions.SChannel_Options property.
 
Finding the hash of a certificate is as easy in powershell as running a dir command on the certificates container.

dir cert:\localmachine\my

The hash is the hexadecimal Thumbprint value.

Directory: Microsoft.PowerShell.Security\Certificate::localmachine\my
Thumbprint                                Subject
----------                                -------
C12A8FC8AE668F866B48F23E753C93D357E9BE10  CN=*.mydomain.com

Once you have the Thumbprint value, you must to set in the TLSOptions.SChannel_Options property the hash
and where is located the certificate.

TLSOptions.IOHandler = iohSChannel
TLSOptions.SChannel_Options.CertHash = <certificate thumbprint>
TLSOptions.SChannel_Options.CertStoreName = <certificate store name>

120
COMPONENTS

TLSOptions.SChannel_Options.CertStorePath = <certificate store path>


TLSOptions.Password = <certificate optional password>

121
COMPONENTS

TsgcWebSocketClient | SChannel Get Con­
nection Info
Once the client has connected to the secure server, you can request info about which Version is using (TLS 1.2,
TLS 1.3...), the cipher used, strength... and more.
 
Call the function GetInfo of the SChannel Handler to access this info. You can access to the SSL Handler, using
the method OnSSLAfterCreateHandler, which is called after the SChannel Handler is created. After the client con­
nects to server and if the SSL Handler is assigned, call the function GetInfo and if successful, will return the con­
nection data.
 

var
  SSL: TsgcIdSSLIOHandlerSocketSChannel;

oClient := TsgcWebSocketClient.Create(nil);
oClient.URL := 'wss://www.esegece.com:2053';
oClient.TLSOptions.Version := tls1_2;
oClient.TLSOptions.IOHandler := iohSChannel;
oClient.OnSSLAfterCreateHandler := OnSSLAfterCreateHandlerEvent;
oClient.OnConnect := OnConnectEvent;
oClient.Active := True;

procedure OnSSLAfterCreateHandlerEvent(Sender: TObject; aType: TwsSSLHandler;


  aSSLHandler: TIdSSLIOHandlerSocketBase);
begin
  if aSSLHandler.ClassType = TsgcIdSSLIOHandlerSocketSChannel  then
    SSL := TsgcIdSSLIOHandlerSocketSChannel(aSSLHandler);
end;

procedure OnConnectEvent(Connection: TsgcWSConnection);


var
  oInfo: TsgcSChannelConnectionInfo;
begin
  if Assigned(SSL) then
  begin
    oInfo := SSL.GetInfo;
    if (oInfo.Protocol <> tls1_2) then
      raise Exception.Create('Client cannot connect using TLS 1.2');
  end;
end;

122
COMPONENTS

TsgcWebSocketClient | Client Send Text


Message
Once client has connected to server, it can send Text Messages to server. To send a Text Message, just call Write­
Data() method and send your text message.
 

Send a Text Message


Call To WriteData() method and send a Text message. This method is executed on the same thread that is called.

TsgcWebSocketClient1.WriteData('My First sgcWebSockets Message!.');

If QueueOptions.Text has a different value from qmNone, instead of be processed on the same thread that is
called, it will be processed on a secondary thread. By default this option is disabled.

123
COMPONENTS

TsgcWebSocketClient | Client Send Binary


Message
Once client has connected to server, it can send Binary Messages to server. To send a Text Message, just call
WriteData() method and send your binary message.
 

Send a Binary Message


Call To WriteData() method and send a Binary message. This method is executed on the same thread that is
called.
 

oStream := TMemoryStream.Create(nil);
Try
  ...
  TsgcWebSocketClient1.WriteData(oStream);
Finally  
  oStream.Free;
End;

If QueueOptions.Binary has a different value from qmNone, instead of be processed on the same thread that is
called, it will be processed on a secondary thread. By default this option is disabled.
 

124
COMPONENTS

TsgcWebSocketClient | Client Send a Text


and Binary Message
WebSocket protocol only allows to types of messages: Text or Binary. But you can't send a binary with text in the
same message.
One way to solve this, is add a header to binary message before is sent and decode this binary message when is
received.
 
There are 2 functions in sgcWebSocket_Helpers which can be used to set a short description of binary packet, ba­
sically adds a header to stream which is used to identify binary packet.
 
Before send a binary message, call method to encode stream.
 

sgcWSStreamWrite('00001', oStream);
TsgcWebSocketClient1.WriteData(oStream);

 
When binary message is received, call method to decode stream.

sgcWSStreamRead(oStream, vID);

The only limitation is that text used to identify binary message, has a maximum length of 10 characters (this can be
modified if you have access to source code).
 

125
COMPONENTS

TsgcWebSocketClient | Receive Text Mes­
sages
When client receives a Text Message, OnMessage event is fired, just read Text parameter to know the string of
message received.

procedure OnMessage(Connection: TsgcWSConnection; const Text: string);


begin
  ShowMessage('Message Received from Server: ' + Text);
end;

By default, client uses neAsynchronous method to dispatch OnMessage event, this means that this event is exe­
cuted on the context of Main Thread, so it's thread-safe to update any control of a form for example.
 
If your client receives lots of messages or you need to control the synchronization with other threads, set Noti­
fyEvents property to neNoSync, this means that OnMessage event will be executed on the context of connec­
tion thread, so if you require to update any control of a form or access shared objects, you must implement your
own synchronization methods.

126
COMPONENTS

TsgcWebSocketClient | Receive Binary Mes­
sages
When client receives a Binary Message, OnBinary event is fired, just read Data parameter to know the binary mes­
sage received.

procedure OnBinary(Connection: TsgcWSConnection; const Data: TMemoryStream);


var
  oBitmap: TBitmap;
begin
  oBitmap := TBitmap.Create;
  Try
    oBitmap.LoadFromStream(Data);
    Image1.Picture.Assign(oBitmap);
    Log(
      '#image uncompressed size: ' + IntToStr(Data.Size) +
      '. Total received: ' + IntToStr(Connection.RecBytes));
  Finally
    FreeAndNil(oBitmap);
  End;
end;

By default, client uses neAsynchronous method to dispatch OnMessage event, this means that this event is exe­
cuted on the context of Main Thread, so it's thread-safe to update any control of a form for example.
 
If your client receives lots of messages or you need to control the synchronization with other threads, set
NotifyEvents property to neNoSync, this means that OnMessage event will be executed on the context of connec­
tion thread, so if you require to update any control of a form or access shared objects, you must implement
your own synchronization methods.

127
COMPONENTS

TsgcWebSocketClient | Client Authentication


TsgcWebSocket client supports 4 types of Authentications:
 
• Basic: sends an HTTP Header during WebSocket HandShake with User and Password encoded as Basic
Authorization.
• Token: sends a Token as HTTP Header during WebSocket HandShake, just set in
Authentication.Token.AuthToken the required token by server.
• Session: first client request an HTTP session to server and if server returns a session this is passed in GET
HTTP Header of WebSocket HandShake. (* own authorization method for sgcWebSockets library).
• URL: client request authorization using GET HTTP Header of WebSocket HandShake. (* own authorization
method for sgcWebSockets library).
 

Authorization Basic
Is a simple authorization method where user and password are encoded and passes as an HTTP Header. Just set
User and Password and enable only Basic Authorization type to use this method.

oClient := TsgcWebSocketClient.Create(nil);
oClient.Authorization.Enabled := true;
oClient.Authorization.Basic.Enabled := true;
oClient.Authorization.User := 'your user';
oClient.Authorization.Password := 'your password';
oClient.Authorization.Token.Enabled := false;
oClient.Authorization.URL.Enabled := false;
oClient.Authorization.Session.Enabled := false;
oClient.Active := True;

Authorization Token
Allows to get Authorization using JWT, requires you obtain a Token using any external tool (example: using an
HTTP connection, OAuth2...).
If you Attach an OAuth2 component, you can obtain this token automatically. Read more about OAuth2.
Basically you must set your AuthToken and enable Token Authentication.

oClient := TsgcWebSocketClient.Create(nil);
oClient.Authorization.Enabled := true;
oClient.Authorization.Token.Enabled := true;
oClient.Authorization.Token.AuthToken := 'your token';
oClient.Authorization.Basic.Enabled := false;
oClient.Authorization.URL.Enabled := false;
oClient.Authorization.Session.Enabled := false;
oClient.Active := True;

Authorization Session
First client connects to server using an HTTP connection requesting a new Session, if successful, server returns a
SessionId and client sends this SessionId in GET HTTP Header of WebSockets HandShake.
Requires to set UserName and Password and set Session Authentication to True.

oClient := TsgcWebSocketClient.Create(nil);
oClient.Authorization.Enabled := true;
oClient.Authorization.Session.Enabled := true;
oClient.Authorization.User := 'your user';
oClient.Authorization.Password := 'your password';

128
COMPONENTS

oClient.Authorization.Basic.Enabled := false;
oClient.Authorization.URL.Enabled := false;
oClient.Authorization.Token.Enabled := false;
oClient.Active := True;

Authorization URL
This Authentication method, just passes username and password in GET HTTP Header of WebSockets Hand­
Shake.
 

oClient := TsgcWebSocketClient.Create(nil);
oClient.Authorization.Enabled := true;
oClient.Authorization.URL.Enabled := true;
oClient.Authorization.User := 'your user';
oClient.Authorization.Password := 'your password';
oClient.Authorization.Basic.Enabled := false;
oClient.Authorization.Session.Enabled := false;
oClient.Authorization.Token.Enabled := false;
oClient.Active := True;

129
COMPONENTS

TsgcWebSocketClient | Client Exceptions


Sometimes there are some errors in communications, server can disconnect a connection because it's not autho­
rized or a message hasn't the correct format... there are 2 events where errors are captured

OnError

This event is fired every time there is an error in WebSocket protocol, like invalid message type, invalid utf8 string...

procedure OnError(Connection: TsgcWSConnection; const Error: string);


begin
  WriteLn('#error: ' + Error);
end;

OnException

This event is fired every time there is an exception like write a socket is not active, access to an object that not ex­
ists
 

procedure OnException(Connection: TsgcWSConnection; E: Exception);


begin
  WriteLn('#exception: ' + E.Message);
end;

By default, when connection is closed by server, an exception will be fired, if you don't want that these excep­
tions are fired, just disable in Options.RaiseDisconnectExceptions.

130
COMPONENTS

TsgcWebSocketClient | WebSocket Hand­
Shake
WebSocket protocol uses an HTTP HandShake to upgrade from HTTP Protocol to WebSocket protocol. This hand­
shake is handled internally by TsgcWebSocket Client component, but you can add your custom HTTP headers if
server requires some custom HTTP Headers info.

Example: if you need to add this HTTP Header "Client: sgcWebSockets"

procedure OnHandshake(Connection: TsgcWSConnection; var Headers: TStringList);


begin
  Headers.Add('Client: sgcWebSockets');
end;

You can check HandShake string before is sent to server using OnHandShake event too.

131
COMPONENTS

TsgcWebSocketClient | Client Register Pro­
tocol
By default, TsgcWebSocketClient doesn't make use of any SubProtocol, basically websocket sub-protocol are built
on top of websocket protocol and defines a custom message protocol, example of websocket sub-protocols can be
MQTT, STOMP...
 
WebSocket SubProtocol name is sent as an HTTP Header in WebSocket HandShake, this header is processed by
server and if server supports this subprotocol will accept connection, if is not supported, connection will be closed
automatically
 
Example: connect to a websocket server with SubProtocol name 'myprotocol'
 

Client := TsgcWebSocketClient.Create(nil);
Client.Host := 'server host';
Client.Port := server.port;
Client.RegisterProtocol('myprotocol');
Client.Active := True;

132
COMPONENTS

TsgcWebSocketClient | Client Proxies


TsgcWebSocket client support connections through proxies, to configure a proxy connection, just fill the Proxy
properties of TsgcWebSocket client.
 

Client := TsgcWebSocketClient.Create(nil);
Client.Proxy.Enabled := true;
Client.Proxy.Username := 'user';
Client.Proxy.Password := 'secret';
Client.Proxy.Host := '80.55.44.12';
Client.Proxy.Port := 8080;
Client.Active := True;

133
COMPONENTS

TsgcWebSocketServer
TsgcWebSocketServer implements Server WebSocket Component and can handle multiple threaded client connec­
tions. Follow the next steps to configure this component:
 
1. Drop a TsgcWebSocketServer component onto the form
 
2. Set Port (default is 80). If you are behind a firewall probably you will need to configure it.
 
3. Set Specifications allowed, by default all specifications are allowed.
 
    RFC6455: is standard and recommended WebSocket specification.
 
    Hixie76: it's a draft and it's only recommended to establish Hixie76 connections if you want to provide support to
old browsers like Safari 4.2
 
4. If you want, you can handle events:
 
    OnConnect: every time a WebSocket connection is established, this event is fired.
 
    OnDisconnect: every time a WebSocket connection is dropped, this event is fired.
 
    OnError: every time there is a WebSocket error (like mal-formed handshake), this event is fired.
 
    OnMessage: every time a client sends a text message and it's received by server, this event is fired.
 
    OnBinary: every time a client sends a binary message and it's received by server, this event is fired.
 
    OnHandhake: this event is fired after the handshake is evaluated on the server side.
 
    OnException: every time an exception occurs, this event is fired.
 
    OnAuthentication: if authentication is enabled, this event is fired. You can check user and password passed by
the client and enable/disable Authenticated Variable.
 
    OnUnknownProtocol: if WebSocket protocol is not detected (because the client is using plain TCP protocol for
example), in this event connection can be accepted or rejected.
 
    OnStartup: raised after the server has started.
 
    OnShutdown: raised after the server has stopped.
 
    OnTCPConnect: public event, is called AFTER the TCP connection and BEFORE Websocket handshake. Is
useful when your server accepts plain TCP connections (because OnConnect event is only fired after first message
sent by client).
 
    OnBeforeHeartBeat: if HeartBeat is enabled, allows to implement a custom HeartBeat setting Handled parame­
ter to True (this means, standard websocket ping won't be sent).
 
 
 
 
5. Create a procedure and set property Active = True.
 
 

Most common uses


• Start
• Server Start
• Server Bindings

134
COMPONENTS

• Server Startup - Shutdown


• Server Keep Active
 
• Connections
• Server Keep Connections Alive
• Server Plain TCP
 
• Authentication
• Server Authentication
 
• Send Messages
• Server Send Text Message
• Server Send Binary Message
 
• Receive Messages
• Server Receive Text Message
• Server Receive Binary Message
 

Methods
    Broadcast: sends a message to all connected clients.
 
Message / Stream: message or stream to send to all clients.
 
Channel: if you specify a channel, the message will be sent only to subscribers.
 
Protocol: if defined, the message will be sent only to a specific protocol.
 
Exclude: if defined, list of connection guid excluded (separated by comma).
 
Include: if defined, list of connection guid included (separated by comma).
 
    WriteData: sends a message to a single or multiple clients. Every time a Client establishes a
WebSocket connection, this connection is identified by a Guid, you can use this Guid to send a mes­
sage to a client.
 
    Ping: sends a ping to all connected clients. If a time-out is specified, it waits a response until a
time-out is exceeded, if no response, then closes the connection.
 
    DisconnectAll: disconnects all active connections.
 
    Start: uses a secondary thread to connect to the server, this prevents your application freezes
while trying to connect.
 
    Stop: uses a secondary thread to disconnect from the server, this prevents your application
freezes while trying to disconnect.
 
 
 

Properties
    Authentication: if enabled, you can authenticate WebSocket connections against a username and password.
 
Authusers: is a list of authenticated users, following spec:
 
user=password
 
       Implements 3 types of WebSocket Authentication
 
Session: client needs to do an HTTP GET passing username and password, and if authenticated, server re­
sponse a Session ID. With this Session ID, client open WebSocket connection passing as a parameter.

135
COMPONENTS

 
URL: client open Websocket connection passing username and password as a parameter.
 
Basic: implements Basic Access Authentication, only applies to VCL Websockets (Server and Client) and
HTTP Requests (client web browsers don't implement this type of authentication).
 
 
    Bindings: used to manage IP and Ports.
 
    Connections: contains a list of all clients connections.
 
    Count: Connections number count.
 
    LogFile: if enabled save socket messages to a specified log file, useful for debugging.
 
Enabled: if enabled every time a message is received and sent by socket it will be saved on a file.
 
FileName: full path to the filename.
 
UnMaskFrames: by default True, means that saves the websocket messages received unmasked.
 
    Extensions: you can enable compression on messages sent (if client don't support compression, messages will
be exchanged automatically without compression).
 
    FallBack: if WebSockets protocol it's not supported natively by the browser, you can enable the following fall­
backs:
 
      Flash: if enabled, if the browser hasn't native WebSocket implementation and has flash enabled, it uses Flash
as a Transport.
 
      ServerSentEvents: if enabled, allows to send push notifications from the server to browser clients.
 
  Retry: interval in seconds to try to reconnect to server (3 by default).
 
     HeartBeat: if enabled try to keeps alive Websocket client connections sending a ping every x seconds.
 
Interval: number of seconds between each ping.
 
Timeout: max number of seconds between a ping and pong.
 
     TCPKeepAlive: if enabled, uses keep-alive at TCP socket level, in Windows will enable
SIO_KEEPALIVE_VALS if supported and if not will use keepalive. By default is disabled.
 
Interval: in milliseconds.
 
Timeout: in milliseconds.
 
    HTTP2Options: by default HTTP/2 protocol is not enabled, it uses HTTP 1.1 to handle HTTP requests. Enabled
this property if you want use HTTP/2 protocol if client supports it.
 
Enabled: if true, HTTP/2 protocol is supported. If client doesn't supports HTTP/2, HTTP 1.1 will be used as
fallback.
 
Settings: Specifies the header values to send to the HTTP/2 server.
 
EnablePush: by default enabled, this setting can be used to avoid server push content to client.
 
HeaderTableSize: Allows the sender to inform the remote endpoint of the maximum size of the head­
er compression table used to decode header blocks, in octets. The encoder can select any size equal
to or less than this value by using signaling specific to the header compression format inside a header
block. The initial value is 4,096 octets.
 
InitialWindowSize: Indicates the sender’s initial window size (in octets) for stream-level flow control.
The initial value is 65,535 octets. This setting affects the window size of all streams.
 

136
COMPONENTS

MaxConcurrentStreams: Indicates the maximum number of concurrent streams that the sender will
allow. This limit is directional: it applies to the number of streams that the sender permits the receiver
to create. Initially, there is no limit to this value.
 
MaxFrameSize: Indicates the size of the largest frame payload that the sender is willing to receive, in
octets. The initial value is 16,384 octets.
 
MaxHeaderListSize: This advisory setting informs a peer of the maximum size of header list that the
sender is prepared to accept, in octets. The value is based on the uncompressed size of header
fields, including the length of the name and value in octets plus an overhead of 32 octets for each
header field.
 
    IOHandlerOptions: by default uses normal Indy Handler (every connection runs in his own thread)
 
iohDefault: default indy IOHandler, every new connection creates a new thread.
 
iohIOCP: only for windows and requires custom indy version, a thread pool handles all connections. Read
more about IOCP.
 
    LoadBalancer: it's a client which connects to Load Balancer Server to broadcast messages and send informa­
tion about the server.
 
      AutoRegisterBindings: if enabled, sends automatically server bindings to load balancer server.
 
      AutoRestart: time to wait in seconds after a load balancer server connection has been dropped and tries to re­
connect; zero means no restart (by default);
 
      Bindings: here you can set manual bindings to be sent to Load Balancer Server, example:
 
WS://127.0.0.1:80
WSS://127.0.0.2:8888
 
Enabled: if enabled, it will connect to Load Balancer Server.
 
Guid: used to identify server on Load Balancer Server side.
 
Host: Load Balancer Server Host.
 
Port: Load Balancer Server Port.
 
 
    MaxConnections: max connections allowed (if zero there is no limit).
 
    NotifyEvents: defines which mode to notify WebSocket events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 
     Options:
 
FragmentedMessages: allows handling Fragmented Messages
 
           frgOnlyBuffer: the message is buffered until all data is received, it raises OnBinary or OnMessage
event (option by default)
           frgOnlyFragmented: every time a new fragment is received, it raises OnFragmented Event.
           frgAll: every time a new fragment is received, it raises OnFragmented Event with All data received
from the first packet. When all data is received, it raises OnBinary or OnMessage event.
 
HTMLFiles: if enabled, allows to request Web Browser tests, enabled by default.

137
COMPONENTS

 
JavascriptFiles: if enabled, allows to request Javascript Built-in libraries, enabled by default.
 
RaiseDisconnectExceptions: enabled by default, raises an exception every time there is a disconnection
by protocol error.
 
ReadTimeOut: time in milliseconds to check if there is data in socket connection, 10 by default.
 
WriteTimeOut: max time in milliseconds sending data to other peer, 0 by default (only works under Win­
dows OS).
 
ValidateUTF8: if enabled, validates if the message contains UTF8 valid characters, by default is disabled.
 
 
     QueueOptions: this property allows to queue the messages in an internal queue (instead of send directly) and
send the messages in the context of the connection thread (QueueOptions only works on Indy based servers
where every connection runs in his own thread), this prevents locks when several threads try to send a message
using the same connection. For every message type: Text, Binary or Ping a queue can be configured, by default
the value set is qmNone which means the messages are not queued. The other types, means different queue lev­
els and the difference between them are just the order where are processed (first are processed qmLevel1, then
qmLevel2 and finally qmLevel3).
Example: if Text and Binary messages have the property set to qmLevel2 and Ping to qmLevel1. The server will
process first the Ping messages (so the ping message is sent first than Text or Binary if they are queued at the
same time), and then process the Text and Binary messages in the same queue. QueueOptions is not supported
when IOHandlerOptions = iohIOCP
 
    ReadEmptySource: max number of times an HTTP Connection is read and there is no data received, 0 by de­
fault (means no limit). If the limit is reached, the connection is closed.
 
    SecurityOptions:
 
OriginsAllowed: define here which origins are allowed (by default accepts connections from all origins), if
the origin is not in the list closes the connection. Examples:
 
• Allow all connections to IP 127.0.0.1 and port 5555. OriginsAllowed = "http://127.0.0.1:5555"
• Allow all connections to IP 127.0.0.1 and all ports. OriginsAllowed = "http://127.0.0.1:*"
• Allow all connections from any IP. OriginsAllowed = ""
 
 
    SSL: enables secure connections.
 
    SSLOptions: used to define SSL properties: certificates filenames, password...
 
     ThreadPool: if enabled, when a thread is no longer needed this is put into a pool and marked as inactive (do
not consume CPU cycles), it's useful if there are a lot of short-lived connections.
 
MaxThreads: max number of threads to be created, by default is 0 meaning no limit. If max number is
reached then the connection is refused.
 
PoolSize: size of ThreadPool, by default is 32.
 
OpenSSL_Options:
 
APIVersion: allows to define which OpenSSL API will be used.
oslAPI_1_0: uses API 1.0 OpenSSL, it's latest supported by Indy
oslAPI_1_1: uses API 1.1 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 1.1.1 libraries (with TLS 1.3 support).
oslAPI_3_0: uses API 3.0 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 3.0.0 libraries (with TLS 1.3 support).
LibPath: here you can configure where are located the openSSL libraries
oslpNone: this is the default, the openSSL libraries should be in the same folder where is the
binary or in a known path.
oslpDefaultFolder: sets automatically the openSSL path where the libraries should be located
for all IDE personalities.

138
COMPONENTS

oslpCustomFolder: if this is the option selected, define the full path in the property LibPath­
Custom.
LibPathCustom: when LibPath = oslpCustomFolder define here the full path where are located the
openSSL libraries.
UnixSymLinks: enable or disable the loading of SymLinks under Unix systems (by default is en­
abled, except under OSX64):
oslsSymLinksDefault: by default are enabled except under OSX64 (after MacOS Monterey
fails trying to load the library without version.).
oslsSymLinksLoadFirst: Load SymLinks and do before trying to load the version libraries.
oslsSymLinksLoad: Load SymLinks after trying to load the version libraries.
oslsSymLinksDontLoad: don't load the SymLinks.
ECDHE: if enabled, uses ECDHE instead of RSA as key exchange. Recommended to enable ECD­
HE if you use OpenSSL 1.0.2.
 
    WatchDog: if enabled, restart the server after unexpected disconnection.
 
Interval: seconds before reconnects.
 
Attempts: max number of reconnects, if zero, then unlimited.
 
    Throttle: used to limit the number of bits per second sent/received.
 
 
 
 
 

139
COMPONENTS

TsgcWebSocketServer | Start Server


The first you must set when you want start a Server is set a Listening Port, by default, this is set to port 80 but you
can change for any port.
Once the port is set, there are 2 methods to start a server.
 

Active Property
If you set Active property to true, server will start to listening all incoming connection on port set.

oServer := TsgcWebSocketServer.Create(nil);
oServer.Port := 80;
oServer.Active := true;

If you set Active property to false, server will stop and close all active connections.
 

oServer.Active := false;

Start / Stop methods


 
While if you call Active property the process of start / stop server is done in the same thread, calling Start and Stop
methods will be executed in a secondary thread.
 

oServer := TsgcWebSocketServer.Create(nil);
oServer.Port := 80;
oServer.Start();

If you call Stop() method, server will stop and close all active connections.
 

oServer.Stop();

You can use the method ReStart, to Stop and Start server in a secondary thread.
 
If you change the Port after closing a server, to start listening on a different port, call the method Bindings.Clear()
after closing the server to delete all previous bindings. Otherwise the server will try to bind to the previous bindings.

140
COMPONENTS

TsgcWebSocketServer | Server Bindings


By default, if you only fill Port property, server binds listening port of ALL IPs, so if for example, you have 3 IP:
127.0.0.1, 80.5411.22 and 12.55.41.17. Your server will bind this port on 3 IPs.
Usually is recommended only binding to needed IPs, here is where you can user Bindings property.
Instead of use Port property, just use Binding property and fill with IP and Port required.
 
Example: bind Port 5555 to IP 127.0.0.1 and IP 80.58.25.40
 

oServer := TsgcWebSocketServer.Create(nil);
With oServer.Bindings.Add do
begin
  IP := '127.0.0.1';
  Port := 5555;
end;
With oServer.Bindings.Add do
begin
  IP := '80.58.25.40';
  Port := 5555;
end;
oServer.Active := true;

 
If you change the Port after closing a server, to start listening on a different port, call the method Bindings.Clear()
after closing the server to delete all previous bindings. Otherwise the server will try to bind to the previous bindings.
 

141
COMPONENTS

TsgcWebSocketServer | Server Startup


Shutdown
Once you have set all required configurations of your server, there are 2 useful events to know when server has
started and when has stopped.
 

OnStartup
This event is fired when server has started and can process new connections.
 

procedure OnStartup(Sender: TObject);


begin
  WriteLn('#server started');
end;

OnShutdown
This event is fired after server has stopped and no more connections are accepted.
 

procedure OnShutdown(Sender: TObject);


begin
  WriteLn('#server stopped');
end;

142
COMPONENTS

TsgcWebSocketServer | Server Keep Active


Once server is started and OnShutdown event is fired, sometimes server can stopped for any reason. If you want
to restart server after an unexpected close, you can use WatchDog property
 

WatchDog
If WatchDog is enabled, when server detects a Shutdown, WatchDog try to restart again every X seconds until
server is active again.
 
Example: restart every 10 seconds after an unexpected stop with unlimited attempts.
 

oServer := TsgcWebSocketServer.Create(nil);
oServer.WatchDog.Interval := 10;
oServer.WatchDog.Attempts := 0;
oServer.WatchDog.Enabled := true;
oServer.Active := true;

143
COMPONENTS

TsgcWebSocketServer | Server SSL


Server can be configured to use SSL Certificates, in order to get a Production Server with a server certificate, you
must purchase a Certificate from a well known provider: Namecheap, godaddy, Thawte... For testing purposes
you can use a self-signed certificate (check out in Demos/Chat which uses a self-signed certificate).
 
Certificate must be in PEM format, PEM (from Privacy Enhanced Mail) is defined in RFCs 1421 through 1424, this
is a container format that may include just the public certificate (such as with Apache installs, and CA certificate
files /etc/ssl/certs), or may include an entire certificate chain including public key, private key, and root certificates.
To create a single pem certificate, just open your private key file, copy the contents and paste on certificate file.
 
Example:
 
certificate.crt
 
-----BEGIN CERTIFICATE-----
.....
-----END CERTIFICATE-----
 
certificate.key
 
-----BEGIN PRIVATE KEY-----
.....
-----END PRIVATE KEY-----
 
certificate.pem
 
-----BEGIN PRIVATE KEY-----
.....
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
.....
-----END CERTIFICATE-----
 
 
To enable SSL, just enable SSL property and configure the paths to CertFile, KeyFile and RootFile. If certificate
contains entire certificate (public key, private key...) just set all paths to the same certificate.
 
Another property you must set is SSLOptions.Port, this is the port used for secure connections.
 

Simple SSL Configuration


Example: configure SSL in IP 127.0.0.1 and Port 443
 

oServer := TsgcWebSocketServer.Create(nil);
oServer.SSL := true;
oServer.SSLOptions.CertFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.KeyFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.RootCertFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.Port := 443;
oServer.Port := 443;
oServer.Active := true;

SSL and None SSL


You can allow to server, to listening more than one IP and Port, check Binding article which explains how works.
Server can be configured to allow SSL connections and None SSL connections at the same time (of course listen­

144
COMPONENTS

ing on different ports). You only need to bind to 2 different ports and configure port for ssl connections and port for
none ssl connections.
 
Example: configure server in IP 127.0.0.1, port 80 (none encrypted) and 443 (SSL)
 

oServer := TsgcWebSocketServer.Create(nil);
With oServer.Bindings.Add do
begin
  IP := '127.0.0.1';
  Port := 80;
end;
With oServer.Bindings.Add do
begin
  IP := '127.0.0.1';
  Port := 443;
end;
oServer.Port := 80;
oServer.SSL := true;
oServer.SSLOptions.CertFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.KeyFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.RootCertFile := 'c:\certificates\mycert.pem';
oServer.SSLOptions.Port := 443;
oServer.Active := true;

145
COMPONENTS

TsgcWebSocketServer | Server Keep Con­
nections Alive
Once your client has connected to server, sometimes connection can be closed due to poor signal, connection er­
rors... use Heartbeat to keep connection alive.
 

HeartBeat
HeartBeat property allows to send a Ping every X seconds to maintain connection alive. Some servers, close
TCP connections if there is no data exchanged between peers. HeartBeat solves this problem, sending a ping
every a specific interval. Usually this is enough to maintain a connection active, but you can set a TimeOut interval
if you want to close connection if a response from client is not received after X seconds.
 
Example: send a ping to all connected clients every 30 seconds

oServer := TsgcWebSocketServer.Create(nil);
oServer.HeartBeat.Interval := 30;
oServer.HeartBeat.Timeout := 0;
oServer.HeartBeat.Enabled := true;
oServer.Active := true;

146
COMPONENTS

TsgcWebSocketServer  | Server Plain TCP
WebSocket server accepts WebSocket, HTTP, SSE... protocols, but can work too with plain tcp connections. Read
more about TCP Connections.
 
There are 2 events, which can be used to handle TCP connections better.
 
OnTCPConnect
 
This event is called after a client connects to server and before any handshake between client and server. OnCon­
nect event is only fired after client sends a message (to allow server detect which is the protocol to be used).
 
This event allows to know that a new client is trying to connect to server and server can accept or not the connec­
tion. By default, server always accept connection.
 
 
OnUnknownProtocol
 
This event is called when server receives a first message from client but cannot detect if is any of known protocols.
In this event, server can accept or not protocol
 
 
OnEvent
 
This event is fired after a successful and complete connection, if connection is plain TCP, is fired after protocol is
accepted in OnUnknownProtocol event.

147
COMPONENTS

TsgcWebSocketServer  | Server Close Con­
nection
A single Connection can be closed using Close or Disconnect methods.
 

Disconnect
TsgcWSConnection has a method called Disconnect(), that allows to disconnect connection at socket level. If you
call this method, socket will be disconnected directly without waiting any response from client. You can send a
Close Code with this method.
 

Close
TsgcWSConnection has a method called Close(), which allows to send a message to server requesting to close
connection, if client receives this message, must close the connection and server will receive a notification that con­
nection is closed. You can send a Close Code with this method.
 
 

DisconnectAll
Disconnects all active connections. This method is called automatically before server stops listening, but you can
call this method at any time.

148
COMPONENTS

TsgcWebSocketServer | Server Authentica­
tion
TsgcWebSocket server supports 3 types of Authentications:
 
• Basic: read an HTTP Header during WebSocket HandShake with User and Password encoded as Basic
Authorization.
• Session: first client request an HTTP session to server and if server returns a session this is passed in GET
HTTP Header of WebSocket HandShake. (* own authorization method for sgcWebSockets library).
• URL: read request authorization using GET HTTP Header of WebSocket HandShake. (* own authorization
method for sgcWebSockets library).
 
You can set a list of Authenticated users, using AuthUsers property, just set your users with the following format:
user=password

OnAuthentication
Every time server receives an Authentication Request from a client, this event is called to return if user is authenti­
cated or not.
Use Authenticated parameter to accept or not the connection.
 

procedure OnAuthentication(Connection: TsgcWSConnection; aUser, aPassword: string;


  var Authenticated: Boolean);
begin
  if ((aUser = 'user') and (aPassword = 'secret')) then
    Authenticated := true
  else
    Authenticated := false;
end;

 
 

OnUnknownAuthentication
If Authentication is not supported by default, like JWT, still you can use this event to accept or not the connection.
Just read the parameters and accept or not the connection.
 

procedure OnUnknownAuthentication(Connection: TsgcWSConnection; AuthType, AuthData: string;


  var aUser, aPassword: string; var Authenticated: Boolean);
begin
  if AuthType = 'Bearer' then
  begin
    if AuthData = 'jwt_token' then
      Authenticated := true
    else
      Authenticated := false;
  end
  else
    Authenticated := false;
end;

149
COMPONENTS

TsgcWebSocketServer | Server Send Text


Message
Once client has connected to server, server can send text messages. To send a Text Message, just call WriteData()
method to send a message to a single client or use Broadcast to send a message to all clients.
 

Send a Text Message


Call To WriteData() method and send a Text message.

TsgcWebSocketServer1.WriteData('guid', 'My First sgcWebSockets Message!.');

If QueueOptions.Text has a different value from qmNone, instead of be processed on the same thread that is
called, it will be processed on a secondary thread. By default this option is disabled.
 
QueueOptions doesn't work if the property IOHandlerOptions.IOHandlerType = iohIOCP (due to the IOCP architec­
ture, this feature is not supported).
 
 
You can call to WriteData() method from TsgcWSConnection too, example: send a message to client when con­
nects to server.
 

procedure OnConnect(Connection: TsgcWSConnection);


begin
  Connection.WriteData('Hello From Server');
end;

Send a message to ALL connected clients


Call To Broadcast() method to send a Text message to all connected clients.
 

TsgcWebSocketServer1.Broadcast('Hello From Server');

 
 

150
COMPONENTS

TsgcWebSocketServer | Server Send Binary


Message
Once client has connected to server, server can send binary messages. To send a Binary Message, just call Write­
Data() method to send a message to a single client or use Broadcast to send a message to all clients.
 

Send a Text Message


Call To WriteData() method and send a Binary message.

TsgcWebSocketServer1.WriteData('guid', TMemoryStream.Create);

If QueueOptions.Binary has a different value from qmNone, instead of be processed on the same thread that is
called, it will be processed on a secondary thread. By default this option is disabled.
 
QueueOptions doesn't work if the property IOHandlerOptions.IOHandlerType = iohIOCP (due to the IOCP architec­
ture, this feature is not supported).
 
 
 
You can call to WriteData() method from TsgcWSConnection too, example: send a message to client when con­
nects to server.
 

procedure OnConnect(Connection: TsgcWSConnection);


begin
  Connection.WriteData(TMemoryStream.Create);
end;

Send a message to ALL connected clients


Call To Broadcast() method to send a Binary message to all connected clients.
 

TsgcWebSocketServer1.Broadcast(TMemoryStream.Create);

 
 

151
COMPONENTS

TsgcWebSocketServer | Server Receive Text


Message
When server receives a Text Message, OnMessage event is fired, just read Text parameter to know the string of
message received.

procedure OnMessage(Connection: TsgcWSConnection; const Text: string);


begin
  ShowMessage('Message Received from Client: ' + Text);
end;

By default, server uses neAsynchronous method to dispatch OnMessage event, this means that this event is ex­
ecuted on the context of Main Thread, so it's thread-safe to update any control of a form for example.
 
If your server receives lots of messages or you need to control the synchronization with other threads, set Noti­
fyEvents property to neNoSync, this means that OnMessage event will be executed on the context of connec­
tion thread, so if you require to update any control of a form or access shared objects, you must implement your
own synchronization methods.

152
COMPONENTS

TsgcWebSocketServer | Server Receive Bi­
nary Message
When server receives a Binary Message, OnBinary event is fired, just read Data parameter to know the binary
message received.

procedure OnBinary(Connection: TsgcWSConnection; const Data: TMemoryStream);


var
  oBitmap: TBitmap;
begin
  oBitmap := TBitmap.Create;
  Try
    oBitmap.LoadFromStream(Data);
    Image1.Picture.Assign(oBitmap);
    Log(
      '#image uncompressed size: ' + IntToStr(Data.Size) +
      '. Total received: ' + IntToStr(Connection.RecBytes));
  Finally
    FreeAndNil(oBitmap);
  End;
end;

By default, server uses neAsynchronous method to dispatch OnMessage event, this means that this event is ex­
ecuted on the context of Main Thread, so it's thread-safe to update any control of a form for example.
 
If your server receives lots of messages or you need to control the synchronization with other threads, set Noti­
fyEvents property to neNoSync, this means that OnMessage event will be executed on the context of connec­
tion thread, so if you require to update any control of a form or access shared objects, you must implement your
own synchronization methods.

153
COMPONENTS

TsgcWebSocketServer | Server Read Head­
ers from Client
When client connects to WebSocket server, sends a list of headers with information about client connection. In
order to read these client headers, you can OnHandshake event of Server component, which is called when server
receives the headers from client and before sends a response to client.
Client headers are stores in HeadersRequest property of TsgcWSConnectionServer.
 

procedure OnServerHandshake(Connection: TsgcWSConnection; var Headers: TStringList);


begin
  ShowMessage(TsgcWSConnectionServer(Connection).HeadersRequest.Text);
end;

154
COMPONENTS

TsgcWebSocketHTTPServer
TsgcWebSocketHTTPServer implements Server WebSocket Component and can handle multiple threaded client
connections as TsgcWebSocketServer, and allows to server HTML pages using a built-in HTTP Server, sharing the
same port for WebSocket connections and HTTP requests.
 
Follow the next steps to configure this component:
 
1. Drop a TsgcWebSocketHTTPServer component in the form
 
2. Set Port (default is 80). If you are behind a firewall probably you will need to configure it.
 
3. Set Specifications allowed, by default all specifications are allowed.
 
    RFC6455: is standard and recommended WebSocket specification.
 
    Hixie76: it's a draft and it's only recommended to establish Hixie76 connections if you want to provide support to
old browsers like Safari 4.2
 
4. If you want, you can handle events:
 
    OnConnect: every time a WebSocket connection is established, this event is fired.
 
    OnDisconnect: every time a WebSocket connection is dropped, this event is fired.
 
    OnError: every time there is a WebSocket error (like mal-formed handshake), this event is fired.
 
    OnMessage: every time a client sends a text message and it's received by server, this event is fired.
 
    OnBinary: every time a client sends a binary message and it's received by server, this event is fired.
 
    OnHandhake: this event is fired after handshake is evaluated on the server side.
 
    OnCommandGet: this event is fired when HTTP Server receives a GET, POST or HEAD command requesting a
HTML page, an image... Example:
 
AResponseInfo.ContentText := '<HTML><HEADER>TEST</HEAD><BODY>Hello!</BODY></
HTML>';
 
    OnCommandOther: this event is fired when HTTP Server receives a command different of GET, POST or
HEAD.
 
    OnCreateSession: this event is fired when HTTP Server creates a new session.
 
    OnInvalidSession: this event is fired when an HTTP request is using an invalid/expiring session.
 
    OnSessionStart: this event is fired when HTTP Server starts a new session.
 
    OnCommandOther: this event is fired when HTTP Server closes a session.
 
    OnException: this event is fired when HTTP Server throws an exception.
 
    OnAuthentication: if authentication is enabled, this event if fired. You can check user and password passed by
the client and enable/disable Authenticated Variable.
 
    OnUnknownProtocol: if WebSocket protocol is not detected (because the  client is using plain TCP protocol for
example), in this event connection can be accepted or rejected.
 
    OnBeforeHeartBeat: if HeartBeat is enabled, allows to implement a custom HeartBeat setting Handled parame­
ter to True (this means, standard websocket ping won't be sent).
 

155
COMPONENTS

    OnBeforeForwardHTTP: allows to forward a HTTP request to another HTTP server. Use forward property to en­
able this and set the destination URL.
 
    OnHTTPUploadBeforeSaveFile: the event is fired when a new file has been uploaded and before is saved to
disk file, allows to modify the filename where will be saved.
 
    OnHTTPUploadAfterSaveFile: the event is fired after a new file has been uploaded and saved to disk file.
 
 
 
* In some cases, you may get a high consume of cpu due to unsolicited connections, in these cases, just return an
error 500 if it's a HTTP request or close connection for Unknown Protocol requests.
 
 
 
5. Create a procedure and set property Active = true.
 
 

Most common uses


• HTTP
• HTTP Server Requests
• HTTP Dispatch Files
• HTTP/2 Server
• HTTP/2 Server Push
• HTTP/2 Alternate Service
• HTTP Post Big Files
• HTTP 404 Error without Response Body
 
• Other
• HTTP Server Sessions
 

Methods
Broadcast: sends a message to all connected clients.
 
Message / Stream: message or stream to send to all clients.
 
Channel: if you specify a channel, the message will be sent only to subscribers.
 
Protocol: if defined, the message will be sent only to a specific protocol.
 
Exclude: if defined, list of connection guid excluded (separated by comma).
 
Include: if defined, list of connection guid included (separated by comma).
 
    WriteData: sends a message to a single or multiple clients. Every time a Client establishes a
WebSocket connection, this connection is identified by a Guid, you can use this Guid to send a mes­
sage to a client.
 
    Ping: sends a ping to all connected clients.
 
    DisconnectAll: disconnects all active connections.
 

Properties
    Connections: contains a list of all clients connections.

156
COMPONENTS

 
    Bindings: used to manage IP and Ports.
 
    DocumentRoot: here you can define a directory where you can put all html files (javascript, HTML, CSS...) if a
client sends a request, the server automatically will search this file on this directory, if it finds, it will be served.
 
    Extensions: you can enable compression on messages sent (if client don't support compression, messages will
be exchanged automatically without compression).
 
    MaxConnections: max connections allowed (if zero there is no limit).
 
    Count: Connections number count.
 
    AutoStartSession: if SessionState is active, when the server gets a new HTTP request, creates a new session.
 
    SessionState: if active, enables HTTP sessions.
 
    KeepAlive: if enabled, connection will stay alive after the response has been sent.
 
    ReadStartSSL: max. number of times an HTTPS connection tries to start.
 
    SessionList: read-only property used as a container for TIdHTTPSession instances created for the HTTP serv­
er.
 
    SessionTimeOut: timeout of sessions.
 
    HTTP2Options: by default HTTP/2 protocol is not enabled, it uses HTTP 1.1 to handle HTTP requests. Enabled
this property if you want use HTTP/2 protocol if client supports it.
 
Enabled: if true, HTTP/2 protocol is supported. If client doesn't supports HTTP/2, HTTP 1.1 will be used as
fallback.
 
Settings: Specifies the header values to send to the HTTP/2 server.
 
EnablePush: by default enabled, this setting can be used to avoid server push content to client.
 
HeaderTableSize: Allows the sender to inform the remote endpoint of the maximum size of the head­
er compression table used to decode header blocks, in octets. The encoder can select any size equal
to or less than this value by using signaling specific to the header compression format inside a header
block. The initial value is 4,096 octets.
 
InitialWindowSize: Indicates the sender’s initial window size (in octets) for stream-level flow control.
The initial value is 65,535 octets. This setting affects the window size of all streams.
 
MaxConcurrentStreams: Indicates the maximum number of concurrent streams that the sender will
allow. This limit is directional: it applies to the number of streams that the sender permits the receiver
to create. Initially, there is no limit to this value.
 
MaxFrameSize: Indicates the size of the largest frame payload that the sender is willing to receive, in
octets. The initial value is 16,384 octets.
 
MaxHeaderListSize: This advisory setting informs a peer of the maximum size of header list that the
sender is prepared to accept, in octets. The value is based on the uncompressed size of header
fields, including the length of the name and value in octets plus an overhead of 32 octets for each
header field.
 
Events: here you can configure if you want be notified when there is a new HTTP/2 connection or not.
 
OnConnect: if enabled when there is a new HTTP/2 connection, OnConnect event will be called (by
default is disabled).
 
OnDisconnect: if enabled when there is a new HTTP/2 disconnection, OnDisconnect event will be
called (by default is disabled).
 

157
COMPONENTS

    HTTPUploadFiles: by default when a client sends a file using a POST stream, the file is saved in memory. If you
want to save these streams directly as files to avoid memory problems, you set the StreamType to pstFileStream
and the files will be saved in the hard disk. Read more about Post Big Files.
 
MinSize: Minimum size in bytes of the stream to be saved as a file stream. By default is zero, which means
all streams will be saved as FileStreams (if StreamType = pstFileStream).
 
RemoveBoundaries: the files uploaded using POST multipart/form-data, are encapsulated in boundaries, if
this property is enabled, the files will be extracted from boundaries and saved in the hard disk.
 
SaveDirectory: the folder where the files will be saved. If empty, will be saved in the same folder where is
the application.
 
StreamType: the type of the stream where the stream will be saved, by default memory.
 
pstMemoryStream: as memory stream.
pstFileStream: as file stream.
 
 
 
 
 
 

158
COMPONENTS

TsgcWebSocketHTTPServer | HTTP Server


Requests
Use OnCommandGet to handle HTTP client requests. Use the following parameters:
 
• RequestInfo: contains HTTP request information.
 
• ResponseInfo: is the HTTP response to HTTP Request.
• ContentText: is the response in text format.
• ContentType: is the type of Content-Type.
• ResponseNo: number of HTTP response, example: 200.
 
 

procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;


  AResponseInfo: TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document = '/' then
  begin
    AResponseInfo.ContentText := '<html><head><title>Test Page</title></head><body></body></html>';
    AResponseInfo.ContentType := 'text/html';
    AResponseInfo.ResponseNo := 200;
  end;
end;

159
COMPONENTS

TsgcWebSocketHTTPServer | HTTP Dis­
patch Files
When a client request a file, OnCommandGet event is fired, but you can use DocumentRoot property to dispatch
automatically files.
 
Example: if you set DocumentRoot to c:/www/files. Every time a new file is requested, will search in this folder if
file exists and if exists, will be dispatched automatically.

160
COMPONENTS

TsgcWebSocketHTTPServer | HTTP/2 Server


sgcWebSockets HTTP Server allows to handle HTTP/1.1 and HTTP/2.0 requests, you can enable HTTP/2 protocol
using HTTP2Options of Server.
 
Set HTTP2Options.Enabled = true to allow the server to accept HTTP/2 protocol requests. The requests can be
processed by user exactly equal than with HTTP/1.1 protocol, read more.
 
When HTTP/2 protocol is enabled, server will still support HTTP/1.1 requests.
 
By default, OnConnect and OnDisconnect events won't be called when there is a new HTTP/2 connection, but this
can be modified accessing to properties HTTP2Options.Events, here you can customize if you want be notified
every time there is a new HTTP/2 connection and/or disconnection.

161
COMPONENTS

TsgcWebSocketHTTPServer | HTTP/2 Server


Push
HTTP usually works with Request/Response pattern, where client REQUEST a resource to SERVER and SERVER
sends a RESPONSE with the resource requested or an error. Usually the client, like a browser, makes a bunch of
requests for those assets which are provided by the server.
 

 
The main problem of this approach is that first client must send a request to get the resource, example: index.html,
wait till server sends the response, the client reads the content and then make all other requests, example:
styles.css
 
HTTP/2 server push tries to solve this problem, when the client requests a file, if server thinks that this file needs
another file/s, those files will be PUSHED to client automatically.
 

 
In the prior screenshot, first client request index.html, server reads this request and sends as a response 2 files:
index.html and styles.css, so it avoids a second request to get styles.css
 

Configure Server Push


Following the prior screenshots, you can configure your server so every time there is a new request for /index.html
file, server will send index.html and styles.css
 
Use the method PushPromiseAddPreLoadLinks, to associate every request to a push promise list.
 

server := TsgcWebSocketHTTPServer.Create(nil);
oLinks := TStringList.Create;
Try
  oLinks.Add('/styles.css');
  server.PushPromiseAddPreLoadLinks('/index.html', oLinks);
Finally

162
COMPONENTS

  oLinks.Free;
End;

procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo:


TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document = '/index.html' then
  begin
    AResponseInfo.ContentText := '';
    AResponseInfo.ContentType := 'text/html';
    AResponseInfo.ResponseNo := 200;
  end
  else if ARequestInfo.Document = '/styles.css' then
  begin
    AResponseInfo.ContentText := '';
    AResponseInfo.ContentType := 'text/css';
    AResponseInfo.ResponseNo := 200;
  end;
end;

Using the chrome developer tool, you can view how the styles.css file is pushed to client.
 

163
COMPONENTS

TsgcWebSocketHTTPServer | HTTP/2 Alter­
nate Service
The Alt-Svc HTTP header is used to inform the clients that the same resource can be reached from another
service or protocol, this is useful if you want inform the HTTP clients that your server supports HTTP/2 for exam­
ple.
 
Example: if your server is running on a local IP 127.0.0.1 and is listening on 2 ports: 80 (non encrypted) and 443
(encrypted). You can inform the clients, that HTTP/2 is supported on port 443 using the following HTTP header
 
Alt-Svc: h2=":443"
 
When HTTP/2 is enabled, automatically adds this header if the connection is not running on HTTP/2 protocol.
You can enable or disable this feature using the property HTTP2Options.AltSvc.

164
COMPONENTS

TsgcWebSocketHTTPServer | 404 Error with­
out Response Body
By default, the Indy library adds some content body in HTTP responses if there is no ContentText or ContentStream
assigned, if you want to return an empty Response body, because of 404 error or similar, you can use the following
trick.
 
Create a new TStringStream without content and Assign to ContentStream property of HTTP Response, this way
the HTTP Response will be sent without the HTML Tags used by default.
 
Example
 

procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;


  AResponseInfo: TIdHTTPResponseInfo);
begin
  AResponseInfo.ContentStream := TStringStream.Create('');
  AResponseInfo.ContentType := 'text/html';
  AResponseInfo.ResponseNo := 404;
end;

165
COMPONENTS

TsgcWebSocketHTTPServer | Sessions
HTTP is state-less protocol (at least till HTTP 1.1), so client request a file, server sends a response to client and
connection is closed (well, you can enable keep-alive and then connection is not closed immediately, but this is far
beyond the purpose of this article). The use of the sessions, allows to store some information about client, this can
be used during a client login for example. You can use whatever session unique ID, search in the list of sessions if
already exists and if not exists, create a new session. Session can be destroyed after some time without using it or
manually after client logout.
 

Configuration
There are some properties in TsgcWebSocketHTTPServer which enables/disables sessions in server component.
Let's see the most important:
 
Property Description
This is the first property which has to be enabled in order to use Sessions. Without this proper
SessionState
abled, sessions won't work
SessionTimeout Here you must set a value greater than zero (in milliseconds) for max time session will be acti
Sessions can be created automatically (AutoStartSession = true) or manually (AutoStartSessi
AutoStartSession false). If Sessions are created automatically, server will use RemoteIP as unique identifier to s
there is an active session stored.
 
 

TsgcWebSocketHTTPServer1.SessionState := True;
TsgcWebSocketHTTPServer1.SessionTimeout := 600000;
AutoStartSession := False;

Create Session
In order to create a new session, we must create a new session id which is unique, you can use whatever, exam­
ple: if client is authenticating, you can use user + password + remoteip as session id.
Then, we search in Session list if already exists, if not exists, we create a new one.
 
When a new session is create OnSessionStart event is called and when session is closed, OnSessionEnd event
is raised.
 

procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;


  AResponseInfo: TIdHTTPResponseInfo);
var
  vID: String;
  oSession: TIdHTTPSession;
begin
  if ARequestInfo.Document = '/' then
    AResponseInfo.ServeFile(AContext, 'yourpathhere\index.html')
  else
  begin
    // check if user is valid
    if not ((ARequestInfo.AuthUsername = 'user') and (ARequestInfo.AuthPassword = 'pass')) then
      AResponseInfo.AuthRealm := 'Authenticate'
    else
    begin
      // create a new session id with authentication data
      vID := ARequestInfo.AuthUsername + '_' + ARequestInfo.AuthPassword + '_' + ARequestInfo.RemoteIP;
 
      // search session
      oSession := TsgcWebSocketHTTPServer1.SessionList.GetSession(vID, ARequestInfo.RemoteIP);
 

166
COMPONENTS

      // create new session if not exists


      if not Assigned(oSession) then
        oSession := TsgcWebSocketHTTPServer1.SessionList.CreateSession(ARequestInfo.RemoteIP, vID);
 
      AResponseInfo.ContentText := '<html><head></head><body>Authenticated</body></html>';
      AResponseInfo.ResponseNo := 200;
    end;
  end;
end;

 
 
 

167
COMPONENTS

TsgcWebSocketServer_HTTPAPI
The HTTP Server API enables applications to communicate over HTTP without using Microsoft Internet Information
Server (IIS). Applications can register to receive HTTP requests for particular URLs, receive WebSocket requests,
and send WebSocket responses. The HTTP Server API includes SSL support so that applications can exchange
data over secure HTTP connections without IIS. It is also designed to work with I/O completion ports.
 
The server supports the following protocols:
 
• WebSockets (Requires Windows 8 or later)
• HTTP 1.1
• HTTP/2 (Requires Windows 2016+ or Windows 10+).
 
By default, this component requires that your application run as Administrator mode, for URL registration.
If the URL have already be registered using an external tool like netsh, you can run without Admin rights,
disable the property BindingOptions.ConfigureSSLCertificate to allow start the application without admin
rights.
Set FastMM4/FastMM5 as the first unit of your project.
 
Follow the next steps to configure this component:
 
1. Drop a TsgcWebSocketServer_HTTPAPI component in the form
 
2. Define the listening address and port:
 

Server.Host := '127.0.0.1';
Server.Port := 80;

 
 
3. Set Specifications allowed, by default all specifications are allowed.
 
    RFC6455: is standard and recommended WebSocket specification.
 
    Hixie76: it's a draft and it's only recommended to establish Hixie76 connections if you want to provide support to
old browsers like Safari 4.2
 
4. If you want, you can handle events:
 
    OnConnect: every time a WebSocket connection is established, this event is fired.
 
    OnDisconnect: every time a WebSocket connection is dropped, this event is fired.
 
    OnError: every time there is a WebSocket error (like mal-formed handshake), this event is fired.
 
    OnMessage: every time a client sends a text message and it's received by server, this event is fired.
 
    OnBinary: every time a client sends a binary message and it's received by server, this event is fired.
 
    OnHandhake: this event is fired after the handshake is evaluated on the server side.
 
    OnException: this event is fired when HTTP Server throws an exception.
 
    OnAuthentication: if authentication is enabled, this event is fired. You can check user and password passed by
the client and enable/disable Authenticated Variable.
 
    OnUnknownProtocol: this event doesn't work at the moment of write this document.
 
    OnBeforeHeartBeat: if HeartBeat is enabled, allows to implement a custom HeartBeat setting Handled parame­
ter to True (this means, standard websocket ping won't be sent).

168
COMPONENTS

 
    OnAsynchronous: every time an asynchronous event has been completed, this event is called.
 
    OnBeforeForwardHTTP: allows to forward a HTTP request to another HTTP server. Use forward property to en­
able this and set the destination URL.
 
    OnAfterForwardHTTP: allows to know the result of the forwarded request.
 
 
 
5. Create a procedure and set property Active = true
 

URL Reservation
The HTTP.SYS server uses URL reservation to assign which URL endpoints will be used by the HTTP.SYS server.
 
Basic URL Reservation
 
This is the most easy simple mode to configure the Server, basically you only set the Host and Port that the
HTTP.SYS server will handle.
Example: if your server runs on the IP 127.0.0.1 and Port 80, just set the following properties

Server.Host := '127.0.0.1';
Server.Port := 80;

 
If the server runs in more than one IP and you want bind to multiple IPS, use the NewBinding Method. First clear
the Host and Bindings property and then use the NewBinding method to define all Server Bindings.

Server.Host := '';
Server.Bindings.Clear;
Server.Bindings.NewBinding('127.0.0.1', 80, '');
Server.Bindings.NewBinding('80.50.55.11', 80, '');

If the server requires SSL connections, do the following to define the Host and Port which will be used to handle
SSL connections.

Server.Host := '127.0.0.1';
Server.Port := 443;
Server.SSL := True;
Server.SSLOptions.Hash := 'CERTIFICATE_HASH';

If the server requires SSL connections with multiple IP Addresses, first clear the Host and Bindings property and
the register the new Bindings.

Server.Host := '';
Server.Bindings.Clear;
Server.Bindings.NewBinding('127.0.0.1', 443, '', true, 'CERTIFICATE_HASH1');
Server.Bindings.NewBinding('80.50.55.11', 443, '', true, 'CERTIFICATE_HASH2');

Most common uses


• Connection
• OnDisconnect not fired
• SSL
• HTTPAPI Server SSL
• Self-Signed Certiifcates
• HTTP
• Custom Headers
• Send Text Response
• Send File Response
• Post Big Files

169
COMPONENTS

• HTTP/2
• Disable HTTP/2
 
 

Properties
Host: if the property has a value, it will be used to register the URL. If you use the Bindings property to de­
fine the server bindings, clear the value of this property.
 
Port: the default listening port, if the Host property has a value, the Host + Port will be used to register the
URL.
 
Timeouts: allows overriding default timeouts of HTTP API Server.
 
EntityBody: the time, in seconds, allowed for the request entity body to arrive.
DrainEntityBody: The time, in seconds, allowed for the HTTP Server API to drain the entity body on
a Keep-Alive connection.
RequestQueue: The time, in seconds, allowed for the request to remain in the request queue before
the application picks it up.
IdleConnection: The time, in seconds, allowed for an idle connection.
HeaderWait: The time, in seconds, allowed for the HTTP Server API to parse the request header.
MinSendRate: The minimum sends rate, in bytes-per-second, for the response. The default response
sends rate is 150 bytes-per-second.
 
MaxConnections:  maximum number of connections (zero means unlimited, value by default).
 
MaxBandwidth: maximum allowed bandwidth rate in bytes per second (zero means unlimited, value by de­
fault).
 
ThreadPoolSize: by default 32 (maximum allowed is 64), allows setting number of threads of HTTP API
Server.
 
ReadBufferSize: by default 16384, allows to modify the size of the buffer size when read socket data.
 
Asynchronous: by default is disabled, if enabled, messages sent don't wait till completed. You can check
when asynchronous is completed OnAsynchronous event.
 
SSLOptions: here you can customize ssl properties.
 
CertStoreName: allows to set the name of certificate store where is certificate.
Hash: this is the hexadecimal thumbprint value of certificate and is required by server to retrieve cer­
tificate. You can find hash of certificate using powershell, running a "dir" comand on the certificates
store, example: dir cert:\localmachine\my.
 
 

Methods
Broadcast: sends a message to all connected clients.
 
Message / Stream: message or stream to send to all clients.
 
Channel: if you specify a channel, the message will be sent only to subscribers.
 
Protocol: if defined, the message will be sent only to a specific protocol.
 
Exclude: if defined, list of connection guid excluded (separated by comma).
 
Include: if defined, list of connection guid included (separated by comma).
 

170
COMPONENTS

    WriteData: sends a message to a single or multiple clients. Every time a Client establishes a
WebSocket connection, this connection is identified by a Guid, you can use this Guid to send a mes­
sage to a client.
 
    Ping: sends a ping to all connected clients.
 
    DisconnectAll: disconnects all active connections.
 
    HTTPUploadFiles: by default when a client sends a file using a POST stream, the file is saved in memory. If you
want to save these streams directly as files to avoid memory problems, you set the StreamType to pstFileStream
and the files will be saved in the hard disk. Read more about Post Big Files.
 
MinSize: Minimum size in bytes of the stream to be saved as a file stream. By default is zero, which means
all streams will be saved as FileStreams (if StreamType = pstFileStream).
 
RemoveBoundaries: the files uploaded using POST multipart/form-data, are encapsulated in boundaries, if
this property is enabled, the files will be extracted from boundaries and saved in the hard disk.
 
SaveDirectory: the folder where the files will be saved. If empty, will be saved in the same folder where is
the application.
 
StreamType: the type of the stream where the stream will be saved, by default memory.
 
pstMemoryStream: as memory stream.
pstFileStream: as file stream.
 
 
 
 
 

171
COMPONENTS

TsgcWebSocketServer_HTTPAPI | HTTPAPI
Server SSL
Server can be configured to use SSL Certificates, in order to get a Production Server with a server certificate, you
must purchase a Certificate from a well known provider: Namecheap, godaddy, Thawte... For testing purposes
you can use a self-signed certificate (check out in Demos/Chat which uses a self-signed certificate). Read the fol­
lowing article How Create a Self-signed certificate.
 
Once you have your certificate, you must configure in Server which certificate will use to encrypt connections.
 

Certificate Hash
First you need to know which is the Hash of your certificate. Finding the hash of a certificate is as easy in power­
shell as running a dir command on the certificates container.

dir cert:\localmachine\my

The hash is the hexadecimal Thumbprint value.


 

Directory: Microsoft.PowerShell.Security\Certificate::localmachine\my
Thumbprint                                Subject
----------                                -------
C12A8FC8AE668F866B48F23E753C93D357E9BE10  CN=*.mydomain.com

Once you have the Thumbprint value, just set in TsgcWebSocketServer_HTTPAPI.TLSOptions.Hash property.
 
Once you have set hash, just set TsgcWebSocketServer_HTTPAPI.SSL = true and your server is know ready to get
started.

172
COMPONENTS

TsgcWebSocketServer_HTTPAPI | Self-
Signed Certificates
If you require some certificate for your own testings, you can create a self-signed certificate in your testing ma­
chine, follow the next steps:
 
1. Run Powershell as Administrator.
2. Run the following command to create the certificate:
 

New-SelfSignedCertificate -DnsName localhost -CertStoreLocation "cert:\LocalMachine\My"

If successful, you will get a confirmation about new certificate created. Just copy Thumbprint and paste on
TsgcWebSocketServer_HTTPAPI.TLSOptions.Hash property.
 

 
3. Optional, you can add your self-signed certificate as a trusted certificate authority

Run MMC -32 as administrator

3.1. Select File / Add or Remove Snap-in


 
3.2. Select Certificate and then click Add
 
3.3. Select computer account and press Next.
 
3.4. Select Local computer and press Ok. You will now your Certificates.
 
4.5. Select your certificate from Personal / Certificates and Paste on Trusted Root Certificates Authorities /
Certificates.

173
COMPONENTS

TsgcWebSocketServer_HTTPAPI | Disable
HTTP/2
HTTP/2 protocol is enabled by default in Server 2016+ and Windows 10+ OS. In some old browsers or HTTP
clients, you might encounter an error because protocol is not fully supported. You can prevent these errors by dis­
abling HTTP/2 protocol.
 
How Disable HTTP/2
 
• Open the Window Registry Editor
• Go to the following registry key:
 
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters
 
• Add the following DWORD values and set both values to zero.
 
• EnableHttp2Tls
• EnableHttp2Cleartext
 
• Reboot the computer.
 
 
 
 

174
COMPONENTS

TsgcWebSocketServer_HTTPAPI | Custom
Headers
You can customize the response of HTTP.SYS server using the CustomHeaders property of response object.
 
Just set the value of CustomHeaders with the Header Name + Header Value separated by NewLine Characters.
 
Example: if you want to add the following headers, find below a sample code
 
Access-Control-Allow-Origin: *
Acces-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE
 

procedure OnHTTPRequest(aConnection: TsgcWSConnection_HTTPAPI; const aRequestInfo: THttpServerRequest;


  var aResponseInfo: THttpServerResponse);
begin
  aResponseInfo.ResponseNo := 200;
  aResponseInfo.CustomHeaders := 'Access-Control-Allow-Origin: *' + #13#10 + 'Acces-Control-Allow-Methods: ' +
    'GET, POST, OPTIONS, PUT, PATCH, DELETE';
end;

175
COMPONENTS

TsgcWebSocketServer_HTTPAPI | Send Text


Response
Use the event OnHTTPRequest to handle the HTTP Requests. 
 
The class THttpServerRequest contains the HTTP Request Data.
 
• Document: the Document the peer is trying to access.
• Method: the HTTP Method ('GET', POST'...)
• Headers: the Headers of HTTP request.
• AcceptEncoding: accept encoding variable, example: "gzip, deflate, br".
• ContentType: example: "text/html"
• Content: content of request if exists.
• QueryParams: the query parameters.
• Cookies: the cookies if exists.
• ContentLength: size of the content.
• AuthExists, AuthUsername, AuthPassword: authentication request data.
• Stream: if the http request has a body, this is the stream of the body.
 
The class THttpServerResponse contains the HTTP response Data.
 
• ContentText: is the response as text.
• ContentType: example: "text/html".
• CustomHeaders: if you need to send your own headers use this variable
• AuthRealm: if the server requires authentication, set this variable.
• ResponseNo: the HTTP response number, example: 200 means the response if correct.
• ContentStream: if the response contains a stream, set here (don't free the stream, it will be freed automati­
cally).
• FileName: if the response is a filename, set here the full path to the filename.
• Date, Expires, LastModified: datetime variables of the response.
• CacheControl: allows to customize the cache behaviour.
 
Example: if the server receives a GET request to the document "/test.html" send a OK response, otherwise send a
404 if it's a GET request or error 500 if it's another method.
 

procedure OnHTTPRequest(aConnection: TsgcWSConnection_HTTPAPI;


const aRequestInfo: THttpServerRequest;
var aResponseInfo: THttpServerResponse);
begin
if aRequestInfo.Method = 'GET' then
begin
if aRequestInfo.Document = '/test.html' then
begin
aResponseInfo.ResponseNo := 200;
aResponseInfo.ContentText := 'OK';
aResponseInfo.ContentType := 'text/html; charset=UTF-8';
end
else
aResponseInfo.ResponseNo := 404;
end
else
aResponseInfo.ResponseNo := 500;
end;

176
COMPONENTS

TsgcWebSocketServer_HTTPAPI | Send File


Response
Use the FileName property of THttpServerResponse object if you want to send a filename as a response to a
HTTP request.
 

procedure OnHTTPRequest(aConnection: TsgcWSConnection_HTTPAPI;


const aRequestInfo: THttpServerRequest;
var aResponseInfo: THttpServerResponse);
begin
if aRequestInfo.Method = 'GET' then
begin
if aRequestInfo.Document = '/test.zip' then
begin
aResponseInfo.ResponseNo := 200;
aResponseInfo.FileName := 'c:\download\test.zip';
aResponseInfo.ContentType := 'application/zip';
end
else
aResponseInfo.ResponseNo := 404;
end
else
aResponseInfo.ResponseNo := 500;
end;

177
COMPONENTS

TsgcWebSocketServer_HTTPAPI | OnDis­
connect not fired
First times working with HTTPAPI Server, it's very common that you will see that OnDisconnect event is not fired
just when client closes connection. The reason is that HTTPAPI Server works a bit differently than other servers like
Indy. In Indy server there is a thread for every connection and this thread is checking every x milliseconds if
connection is active. The HTTPAPI Server uses a thread-pool that handles all connections and it's not check­
ing for every connection if it's active or not.
 
In order to get notified when client closes connection, do the following configuration:
 
1. If you use a TsgcWebSocketClient, set Options.CleanDisconnect := True. This means that before the connec­
tion is closed, the client will try to send a notification to server that connection will be closed. If the server receives
this message, OnDisconnect event will be called.
 
2. For the others disconnections, the only solution is write something to the socket and if fails means the connec­
tion is disconnected. Enable HeartBeat on HTTPAPI server, and send an interval of 60 seconds for example and a
timeout of 0. This configuration means that every 60 seconds all connections will be ping and if any is disconnect­
ed, OnDisconnect event will be fired. You can put a lower value of HeartBeat.Interval, but don't put it too low (1
second for example it's too low) because the performance of the server will be affected.

178
COMPONENTS

TsgcWebSocketClient_WinHTTP
TsgcWebSocketClient implements Client VCL WebSocket Component and can connect to a WebSocket Server, it's
based on WinHTTP API and requires Windows 8 or higher. Follow the next steps to configure this component:
 
1. Drop a TsgcWebSocketClient_WinHTTP component in the form
 
2. Set Host and Port (default is 80) to connect to an available WebSocket Server. You can set URL property and
Host, Port, Parameters... will be updated from URL. Example: wss://127.0.0.1:8080/ws/ will result:

oClient := TsgcWebSocketClient_WinHTTP.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClient.TLS := True;
oClient.Options.Parameters := '/ws/';

 
3. You can select if you want TLS (secure connection) or not, by default is not Activated.
 
4. The following events can be used to customize the websocket client flow:
 
    OnConnect: when a WebSocket connection is established, this event is fired
 
    OnDisconnect: when a WebSocket connection is dropped, this event is fired
 
    OnError: every time there is a WebSocket error (like mal-formed handshake), this event is fired
 
    OnMessage: every time the server sends a text message, this event is fired
 
    OnBinary: every time the server sends a binary message, this event is fired
 
    OnFragmented: when receives a fragment from a message (only fired when Options.FragmentedMessages =
frgAll or frgOnlyFragmented).
 
    OnException: every time an exception occurs, this event is fired.
 
    OnBeforeConnect: before the client tries to connect to server, this event is called.
 
    OnBeforeWatchDog: if WatchDog is enabled, allows to implement a custom WatchDog setting Handled para­
meter to True (this means, won't try to connect to server). You can change the Server Connection properties too
before try to reconnect, example: connect to a fallback server if first fails.
 
 
 
8. Create a procedure and set property Active = True.
 

Methods
 
    WriteData: sends a message to a WebSocket Server. Could be a String or TStream.
 
    Start: uses a secondary thread to connect to the server, this prevents your application freezes while trying to
connect.
 
    Stop: uses a secondary thread to disconnect from the server, this prevents your application freezes while trying
to disconnect.
 
    Connect: try to connect to the server and wait till the connection is successful or there is an error.
 
    Disconnect: try to disconnect from the server and wait till disconnection is successful or there is an error.

179
COMPONENTS

Properties
    Authentication: if enabled, WebSocket connection will try to authenticate passing a username and password.
      
       Implements 1 type of WebSocket Authentication
 
Basic: client open WebSocket connection passing username and password inside the header.
 
    Asynchronous: by default, requests are synchronous, execution of your application stops when you make new
requests and resumes when you get a response. If you don't want that requests stop your application, enable this
property.
 
    Host: IP or DNS name of the server.
 
     HeartBeat: if enabled try to keeps alive a WebSocket connection sending a ping every x seconds.
 
Interval: number of seconds between each ping.
 
Timeout: max number of seconds between a ping and pong.
 
    ReadTimeout: max time in milliseconds to read messages.
 
    Port: Port used to connect to the host.
 
    NotifyEvents: defines which mode to notify websocket events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 
    Options: allows customizing headers sent on the handshake.
 
Parameters: define parameters used on GET.
 
Origin: customize connection origin.
 
FragmentedMessages: allows handling Fragmented Messages
 
           frgOnlyBuffer: the message is buffered until all data is received, it raises OnBinary or OnMessage
event (option by default)
           frgOnlyFragmented: every time a new fragment is received, it raises OnFragmented Event.
           frgAll: every time a new fragment is received, it raises OnFragmented Event with All data received
from the first packet. When all data is received, it raises OnBinary or OnMessage event.
 
    Protocol: if exists, shows the current protocol used
 
    Proxy: here you can define if you want to connect through an HTTP Proxy Server.
 
    WatchDog: if enabled, when an unexpected disconnection is detected, tries to reconnect to the server automati­
cally.
 
Interval: seconds before reconnects.
 
Attempts: max number of reconnects, if zero, then unlimited.
 
    TLS: enables a secure connection.
 

180
COMPONENTS

TsgcWebSocketLoadBalancerServer
TsgcWebSocketLoadBalancerServer allows distributing messages across a group of servers and distributes clients
connections using a random sequence or fewer connections algorithm.
 
Load Balancer Server, inherits all methods and properties from TsgcWebSocketServer.
 
Follow the next steps to configure this component:
 
1. Drop a TsgcWebSocketLoadBalancerServer component in the form
 
2. Set Port (default is 80). If you are behind a firewall probably you will need to configure it.
 
3. Configure LoadBalancer properties:
 
3.1 lbRandom: every time a new client request a new connection, it will return a random server.
 
3.1 lbConnections: every time a new client request a new connection, it will return server with fewer clients
connected.
 
4. There are serveral events which are specific of LoadBalancerServer:
 
    OnBeforeSendServerBinding: raised before binding is sent to a new client connection.
 
    OnClientConnect: every time a client connection is stablished, this event is fired.
 
    OnClientDisconnect: every time a client connection is dropped, this event is fired.
 
    OnClientMessage: raised when a new text message is received from the server.
 
    OnClientBinary: raised when a new binary message is received from the server.
 
    OnClientFragmented: raised when a new fragmented message is received from the server.
 
    OnServerConnect: raised when a new server connects to LoadBalancerServer.
 
    OnServerDisconnect: raised when a server disconnects from LoadBalancerServer.
 
    OnServerReady: raised when a server is ready to accept messages.
 
5. Configure "LoadBalancer" property of back-up servers, to connect to LoadBalancer Server.
 
6. Create a procedure and set property Active = true
 
 
 
 
 
 
 
 
 
 
 

181
COMPONENTS

TsgcWebSocketProxyServer
TsgcWebSocketProxyServer implements a WebSocket Server Component which listens to client WebSocket con­
nections and forwards data connections to a normal TCP/IP server. This is especially useful for browser connec­
tions because allows a browser to virtually connect to any server.
 
 

182
COMPONENTS

TsgcIWWebSocketClient
TsgcIWWebSocketClient implements Intraweb WebSocket Component and can connect to a WebSocket Server.
Follow the next steps to configure this component:
 
1. Drop a TsgcIWWebSocketClient component in the form
 
2. Set Host and Port (default is 80) to connect to an available WebSocket Server. You can set URL property and
Host, Port, Parameters... will be updated from URL. Example: wss://127.0.0.1:8080/ws/ will result:
 

oClient := TsgcIWWebSocketClient.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClient.TLS := True;
oClient.Options.Parameters := '/ws/';

 
3. You can select if you want TLS (secure connection) or not, by default is not Activated.
 
4. Set Transports allowed.
 
    WebSockets: it will use standard WebSocket implementation
 
    Emulation: if browser doesn't support WebSockets, then it will use a loop AJAX callback connection
 
5. If you want, you can handle events
 
    OnAsyncConnect: when a WebSocket connection is established, this event is fired
 
    OnAsyncDisconnect: when a WebSocket connection is dropped, this event is fired
 
    OnAsyncError: every time there is a WebSocket error (like mal-formed handshake), this event is fired
 
    OnAsyncMessage: every time the server sends a message, this event is fired
 
    OnAsyncEmulation: this event is fired on every loop of emulated connection
 
6. Create an Async Procedure and set property Active := True
 
 

Methods

 
    Open: Opens a WebSocket Connection.
 
    Close: Closes a WebSocket Connection.
 
    WriteData: sends a message to WebSocket Server.
 
 

183
COMPONENTS

Properties

 
   Connected: is a read-only variable and returns True if the connection is Active, otherwise returns False.
 
    JSOpen: here you can include JavaScript Code on the client side when a connection is opened.
 
    JSClose: here you can include JavaScript Code on the client side when a connection is closed.
 
    JSMessage: here you can include JavaScript Code on the client side when clients receive a message from
the server. You can get Message String, using Javascript variable "text".
 
    JSError: here you can include JavaScript Code on the client side when an error is raised. You can get
Message Error, using Javascript variable "text".
 

184
COMPONENTS

TsgcWSConnection
TsgcWSConnection is a wrapper of client WebSocket connections, you can access to this object on Server or
Client Events.
 

Methods
  WriteData: sends a message to the client.
 
  Close: sends a close message to other peer. A "CloseCode" can be specified optionally. By default, the value sent
is NORMAL close code. If you send a Negative Close code, the reason of closing won't be sent.
 
  Disconnect: close client connection from the server side. A "CloseCode" can be specified optionally.
 
  Ping: sends a ping to the client.
 
  AddTCPEndOfFrame: if connection is plain TCP, allows to set which byte/s define the end of message. Message
is buffered till is received completely.
 
  Subscribed: returns if the connection is subscribed to a custom channel.
 
  Subscribe: subscribe this connection to a channel. Later you can Broadcast a message from server component
to all connections subscribed to this channel.
 
  UnSubscribe: unsubscribe this from connection from a channel.
 
 

Properties
  Protocol: returns sub-protocol used on this connection.
 
  IP: returns Peer IP Address.
 
  Port: returns Peer Port.
 
  LocalIP: returns Host IP Address.
 
  LocalPort: returns Host Port.
 
  URL: returns URL requested by the client.
 
  Guid: returns connection ID.
 
  HeadersRequest: returns a list of Headers received on Request.
 
  HeadersResponse: returns a list of Headers sent as Response.
 
  RecBytes: number of bytes received.
 
  SendBytes: number of bytes sent.
 
  Transport: returns the transport type of connection:
 
trpRFC6455: a normal WebSocket connection.
 
trpHixie76: a WebSocket connection using draft WebSocket spec.
 
trpFlash: a WebSocket connection using Flash as FallBack.

185
COMPONENTS

 
trpSSE: a Server-Sent Events connection.
 
trpTCP: plain TCP connection.
 
 
TCPEndOfFrameScanBuffer: allows to define which method use to find end of message (if using trpTCP as tans­
port).
 
eofScanNone: every time a new packet arrive, OnBinary event is called.
 
eofScanLatestBytes: if latest bytes are equal to bytes added with AddTCPEndOfFrame method, OnBinary
message is called, otherwise this packet is buffered
 
eofScanAllBytes: search in all packet if find bytes equal to bytes added with AddTCPEndOfFrame method.
If true, OnBinary message is called, otherwise this packet is buffered
 
  Data: user session data object, here you can pass an object and access this every time you need, for example:
you can pass a connection to a database, user session properties...
 
 
 
 

186
COMPONENTS

Protocols
With WebSockets, you can implement Sub-protocols allowing to create customized communications, for example
you can implement a sub-protocol over WebSocket protocol to communicate a customized application using JSON
messages, and you can implement another sub-protocol using XML messages.
 
When a connection is open on the Server side, it will validate if sub-protocol sent by the client is supported by the
server, if not, then it will close the connection. A server can implement several sub-protocols, but only one can be
used on a single connection.
 
Sub-protocols are very useful to create customized applications and be sure that all clients support the same com­
munication interface.
 
Although the protocol name is arbitrary, it's recommended to use unique names like "dataset.esegece.com"
 
With sgcWebSockets package, you can build your own protocols and you can use built-in sub-protocols provided:
 
1. Protocol MQTT: MQTT is a Client Server publish/subscribe messaging transport protocol. It is lightweight, open,
simple, and designed so as to be easy to implement.
 
2. Protocol AppRTC: is a webrtc demo application developed by Google and Mozilla, it enables both browsers to
“talk” to each other using the WebRTC API.
 
3. Protocol WebRTC: open source project aiming to enable the web with Real-Time Communication (RTC) capa­
bilities.
 
4. Protocol Files: implemented using binary messages, provides support for send files: packet size, authorization,
QoS, message acknowledgement and more.
 
5. Protocol SGC: implemented using JSON-RPC 2.0 messages, provides the following patterns: RPC, PubSub,
Transactional Messages, Messages Acknowledgment and more.
 
6. Protocol Dataset: inherits from Default Protocol, can send dataset changes (new record, save record or delete
a record) from the server to clients.
 
7. Protocol Presence:  allows to know who is subscribed to a channel, example: chat rooms, collaborators on a
document, people viewing the same web page, competitors in a game...
 
8. Protocol WAMP 1.0: open WebSocket subprotocol that provides two asynchronous messaging patterns: RPC
and PubSub.
 
9. Protocol WAMP 2.0: open WebSocket subprotocol that provides two asynchronous messaging patterns: RPC
and PubSub.
 
10. Protocol STOMP: STOMP is the Simple (or Streaming) Text Orientated Messaging Protocol. STOMP provides
an interoperable wire format so that STOMP clients can communicate with any STOMP message broker to provide
easy and widespread messaging interoperability among many languages, platforms and brokers.
 
10.1 STOMP for RabbitMQ: client for RabbitMQ Broker.
 
10.2 STOMP for ActiveMQ: client for ActiveMQ Broker.
 
11. Protocol AMQP: Advanced Message Queuing Protocol (AMQP) is created as an open standard protocol that
allows messaging interoperability between systems, regardless of message broker vendor or platform used.
 
If you need to use more than one protocol using a single connection (example: you may need to use default
protocol to handle Remote Procedure Calls and Dataset protocol to handle database connections) you can as­
sign a "Broker" to each protocol component and all messages will be exchanged using this intermediary protocol
(you can check "Tickets Demo" to get a simple example of this).
 

187
COMPONENTS

Protocols can be registered at runtime, just call Method RegisterProtocol and pass protocol component as a pa­
rameter.
 
 

Javascript Reference
Here you can get more information about common javascript library used on sgcWebSockets.

188
COMPONENTS

Protocols Javascript
Default Javascript sgcWebSockets uses sgcWebSocket.js file.
 
Here you can find available methods, you need to replace {%host%} and {%port%} variables as needed, example:
if you have configured your sgcWebSocket server to listen port 80 on www.example.com website you need to con­
figure your access to sgcWebSocket.js file as:
 

<script src="http://www.example.com:80/sgcWebSockets.js"></script>

Open Connection
<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  var socket = new sgcWebSocket('ws://{%host%}:{%port%}');
</script>

 
sgcWebSocket has 3 parameters, only first is required:
 
sgcWebSocket(url, protocol, transport)
 
• URL: WebSocket server location, you can use "ws:" for normal WebSocket connections and "wss:" for
secured WebSocket connections.
 
sgcWebSocket('ws://127.0.0.1')
 
sgcWebSocket('wss://127.0.0.1')
 
• Protocol: if the server accepts one or more protocol, you can define which is the protocol you want to
use.
 
sgcWebSocket('ws://127.0.0.1', 'esegece.com')
 
• Transport: by default, first tries to connect using WebSocket connection and if not implemented by
Browser, then tries Server Sent Events as Transport.
 
Use WebSocket if implemented, if not, then use Server Sent Events:
 
sgcWebSocket('ws://127.0.0.1')
 
Only use WebSocket as transport:
 
sgcWebSocket('ws://127.0.0.1', '', ['websocket'])
 
Only use Server Sent  as transport:
 
sgcWebSocket('ws://127.0.0.1', '', ['sse'])
 

Open Connection With Authentication

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  var socket = new sgcWebSocket({"host":"ws://{%host%}:{%port%}","user":"admin","password":"1234"});
</script>

189
COMPONENTS

Send Message

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  var socket = new sgcWebSocket('ws://{%host%}:{%port%}');
  socket.send('Hello sgcWebSockets!');
</script>

Show Alert with Message Received

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  var socket = new sgcWebSocket('ws://{%host%}:{%port%}');
  socket.on('message', function(event)
  {  
    alert(event.message);
  }
</script>

Binary Message Received

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  var socket = new sgcWebSocket('ws://{%host%}:{%port%}');
  socket.on('stream', function(event)
  {  
    document.getElementById('image').src = URL.createObjectURL(event.stream);
    event.stream = "";
  }
</script>

 
 

Binary (Header + Image) Message Received


 

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  var socket = new sgcWebSocket('ws://{%host%}:{%port%}');
  socket.on('stream', function(event)
  {  
    sgcWSStreamRead(evt.stream, function(header, stream) {
      document.getElementById('text').innerHTML = header;
      document.getElementById('image').src = URL.createObjectURL(event.stream);
      event.stream = "";
    }
  }
</script>

Show Alert OnConnect, OnDisconnect and OnError Events

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  var socket = new sgcWebSocket('ws://{%host%}:{%port%}');

190
COMPONENTS

  socket.on('open', function(event)
  {  
    alert('sgcWebSocket Open!');
  };
  socket.on('close', function(event)
  {  
    alert('sgcWebSocket Closed!');
  };
  socket.on('error', function(event)
  {  
    alert('sgcWebSocket Error: ' + event.message);
  };
</script>

Close Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  socket.close();
</script>

Get Connection Status

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script>
  socket.state();
</script>

191
COMPONENTS

Protocol MQTT
MQTT is a Client-Server publish/subscribe messaging transport protocol. It is light weight, open, simple, and de­
signed so as to be easy to implement. These characteristics make it ideal for use in many situations, including con­
strained environments such as for communication in Machine to Machine (M2M) and the Internet of Things (IoT)
contexts where a small code footprint is required and/or network bandwidth is at a premium.
 
The protocol runs over TCP/IP, or over other network protocols that provide ordered, lossless, bi-directional con­
nections. Its features include:
 
·         Use of the publish/subscribe message pattern which provides one-to-many message distribution and decou­
pling of applications.
 
·         A messaging transport that is agnostic to the content of the payload.
 
·         Three qualities of service for message delivery:
·         "At most once", where messages are delivered according to the best efforts of the operating environ­
ment. Message loss can occur. This level could be used, for example, with ambient sensor data where it
does not matter if an individual reading is lost as the next one will be published soon after.
·         "At least once", where messages are assured to arrive but duplicates can occur.
·         "Exactly once", where message are assured to arrive exactly once. This level could be used, for ex­
ample, with billing systems where duplicate or lost messages could lead to incorrect charges being applied.
 
·         A small transport overhead and protocol exchanges minimized to reduce network traffic.
 
·         A mechanism to notify interested parties when an abnormal disconnection occurs.
 

Features
• Supports 3.1.1 and 5.0 MQTT versions.
• Publish/subscribe message pattern to provide one-to-many message distribution and decoupling of appli­
cations.
• Acknowledgment of messages sent.
• Implements QoS (Quality of Service) for message delivery (all levels: At most once, At least once and Exact­
ly once)
• Last Will Testament.
• Secure connections.
• HeartBeat and Watchdog.
• Authentication to server.

Components
 TsgcWSPClient_MQTT: MQTT Client Component.
 

Most common uses


• Connection
• Client MQTT Connect
• Connect Mosquitto MQTT Servers
• Client MQTT Sessions
• Client MQTT Version
 
• Publish & Subscribe
• MQTT Publish Subscribe
• MQTT Topics
• MQTT Subscribe
• MQTT Publish Message

192
COMPONENTS

• MQTT Receive Messages


• MQTT Publish and Wait Response
 
• Other
• MQTT Clear Retained Messages
 

193
COMPONENTS

TsgcWSPClient_MQTT
The MQTT component provides a lightweight, fully-featured MQTT client implementation with support for versions
3.1.1 and 5.0. The component supports plaintext and secure connections over both standard TCP and WebSock­
ets.
 
Connection to a MQTT server is simple, you need to drop this component in the form and select a TsgcWebSocket­
Client Component using Client Property. Set host and port in TsgcWebSocketClient and set Active := True to con­
nect.
 
MQTT v5.0 is not backward compatible (like v3.1.1). Obviously too many new things are introduced so existing im­
plementations have to be revisited.
 
According to the specification, MQTT v5.0 adds a significant number of new features to MQTT while keeping much
of the core in place.
 
• The Clean Session flag functionality is divided into 2 properties to allow for finer control over session state
data: the CleanStart parameter and the new SessionExpInterval.
• Server disconnect: Allow DISCONNECT to be sent by the Server to indicate the reason the connection is
closed.
• All response packets (CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DIS­
CONNECT) now contain a reason code and reason string describing why operations succeeded or failed.
• Enhanced authentication: Provide a mechanism to enable challenge/response style authentication including
mutual authentication. This allows SASL style authentication to be used if supported by both Client and
Server, and includes the ability for a Client to re-authenticate within a connection.
• The Request / Response pattern is formalized by the addition of the ResponseTopic.
• Shared Subscriptions: Add shared subscription support allowing for load balanced consumers of a subscrip­
tion.
• Topic Aliases can be sent by both client and server to refer to topic filters by shorter numerical identifiers in
order to save bandwidth.
• Servers can communicate what features it supports in ConnectionProperties.
• Server reference: Allow the Server to specify an alternate Server to use on CONNACK or DISCONNECT.
This can be used as a redirect or to do provisioning.
• More: message expiration, Receive Maximums and Maximum Packet Sizes, and a Will Delay interval are all
supported.
 

Methods
  Connect: this method is called automatically after a successful WebSocket connection.
 
  Ping: Sends a ping to the server, usually to keep the connection alive. If you enable HeartBeat property, ping will
be sent automatically by a defined interval.
 
  Subscribe: subscribe client to a custom channel. If the client is subscribed, OnMQTTSubscribe event will be
fired.
SubscribeProperties: (New in MQTT 5.0)
 
• SubscriptionIdentifier: MQTT 5 allows clients to specify a numeric subscription identifier which will
be returned with messages delivered for that subscription. To verify that a server supports subscrip­
tion identifiers, check the "SubscriptionIdentifiersAvailable"
• UserProperties: This property is intended to provide a means of transferring application layer name-
value tags whose meaning and interpretation are known only by the application programs responsible
for sending and receiving them.
 
Example:
 

oProperties := TsgcWSMQTTSubscribe_Properties.Create;
Try

194
COMPONENTS

  oProperties.SubscriptionIdentifier := 16385;
  MQTT.Subscribe('myChannel', mtqsAtMostOnce, oProperties);
Finally
  FreeAndNil(oProperties);
End;

  Unsubscribe: unsubscribe client to a custom channel. If the client is unsubscribed, OnMQTTUnsubscribe event
will be fired.
UnsubscribeProperties: (New in MQTT 5.0)
 
• UserProperties: This property is intended to provide a means of transferring application layer name-
value tags whose meaning and interpretation are known only by the application programs responsible
for sending and receiving them.
 
Example:
 

oProperties := TsgcWSMQTTUnsubscribe_Properties.Create;
Try
  oProperties.UserProperties.Add('Temp=21');
  oProperties.UserProperties.Add('Humidity=55');
  MQTT.UnSubscribe('myChannel', mtqsAtMostOnce, oProperties);
Finally
  FreeAndNil(oProperties);
End;

 
  Publish: sends a message to all subscribed clients. There are the following parameters:
Topic: is the channel where the message will be published.
Text: is the text of the message.
QoS: is the Quality Of Service of published message. There are 3 possibilities:
 
mtqsAtMostOnce: (by default) the message is delivered according to the best efforts of the underly­
ing TCP/IP network. A response is not expected and no retry semantics are defined in the protocol.
The message arrives at the server either once or not at all.
mtqsAtLeastOnce: the receipt of a message by the server is acknowledged by an ACKNOWLEDG­
MENT message. If there is an identified failure of either the communications link or the sending de­
vice or the acknowledgement message is not received after a specified period of time, the sender re­
sends the message. The message arrives at the server at least once. A message with QoS level 1
has an ID param in the message.
mtqsExactlyOnce: where message are assured to arrive exactly once. This level could be used, for
example, with billing systems where duplicate or lost messages could lead to incorrect charges being
applied. If there is an identified failure of either the communications link or the sending device, or the
acknowledgement message is not received after a specified period of time, the sender resends the
message.
 
Retain: if True, Server MUST store the Application Message and its QoS, so that it can be delivered to fu­
ture subscribers whose subscriptions match its topic name. By default is False.
PublishProperties: (New in MQTT 5.0)
 
• PayloadFormat: select payload format from: mqpfUnspecified (which is equivalent to not sending a
Payload Format Indicator) or mqpfUTF8 (Message s UTF-8 Encoded Character Data).
• MessageExpiryInterval: Length of time after which the server must stop delivery of the publish mes­
sage to a subscriber if not yet processed.
• TopicAlias: is an integer value that is used to identify the Topic instead of using the Topic Name. This
reduces the size of the PUBLISH packet, and is useful when the Topic Names are long and the same
Topic Names are used repetitively within a Network Connection.
• ResponseTopic: is used as the Topic Name for a response message.
• CorrelationData: The Correlation Data is used by the sender of the Request Message to identify
which request the Response Message is for when it is received.
• UserProperties: This property is intended to provide a means of transferring application layer name-
value tags whose meaning and interpretation are known only by the application programs responsible
for sending and receiving them.
• SubscriptionIdentifier: A numeric subscription identifier included in SUBSCRIBE packet which will
be returned with messages delivered for that subscription.
• ContentType: String describing content of message to be sent to all subscribers receiving the mes­
sage.

195
COMPONENTS

 
 PublishAndWait: is the same method than Publish, but in this case, if QoS is [mtqsAtLeastOnce, mtqsExactly­
Once] waits till server processes the message, this way, if you get a positive result, means that message has been
received by server. There is a timeout of 10 seconds by default, if after the timeout there is no response from serv­
er, the response will be false.
 
  Disconnect: disconnects from MQTT server.
ReasonCode: code identifies reason why disconnects.(New in MQTT 5.0)
DisconnectProperties (New in MQTT 5.0)
 
• SessionExpiryInterval: Session Expiry Interval in seconds.
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client including diagnostic information.
• ServerReference: can be used by the Client to identify another Server to use.
 
  Auth:  is sent from Client to Server or Server to Client as part of an extended authentication exchange, such as
challenge / response authentication. (New in MQTT 5.0)
ReAuthenticate: if True Initiate a re-authentication, otherwise continue the authentication with another step.
AuthProperties
 
• AuthenticationMethod: contains the name of the authentication method.
• AuthenticationData: contains authentication data.
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client including diagnostic information.
 
 
 
 

Events
  OnMQTTBeforeConnect: this event is fired before a new connection is established. There are 2 parameters:
CleanSession: if True (by default), the server must discard any previous session and start a new session. If
false, the server must resume communication.
ClientIdentifier: every new connection needs a client identifier, this is set automatically by component, but
can be modified if needed.
 
  OnMQTTConnect: this event is fired when the client is connected to MQTT server. There are 2 parameters:
Session:
1. If client sends a connection with CleanSession = True, then Server Must respond with Session =
False.
2. If client sends a connection with CleanSession = False:
 
• If the Server has stored Session state, Session = True.
• If the Server does not have stored Session state, Session = False
ReasonCode: returns code with the result of connection.(New in MQTT 5.0)
ReasonName: text description of ReturnCode.(New in MQTT 5.0)
ConnectProperties: (New in MQTT 5.0)
 
• SessionExpiryInterval: Session Expiry Interval in seconds.
• ReceiveMaximum: number of QoS 1 and QoS 2 publish messages, the server will process concur­
rently for the client.
• MaximumQoS: maximum accepted QoS of PUBLISH messages to be received by the server.
• RetainAvailable: indicates whether the client may send PUBLISH packets with Retain set to True.
• MaximumPacketSize: maximum packet size in bytes the server is willing to accept.
• AssignedClientIdentifier: the Client Identifier which was assigned by the Server when client didn't
send any.
• TopicAliasMaximum: indicates the hishest value that the server will accept as a Topic Alias sent by
the client.
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client including diagnostic information.

196
COMPONENTS

• WildcardSubscriptionAvailable: indicates whether the server supports wildcard subscriptions.


• SubscriptionIdentifiersAvailable: indicates whether the server supports subscription identifiers.
• SharedSubscriptionAvailable: indicates whether the server supports shared subscriptions.
• ResponseInformation: used as the basis for creating a Response Topic.
• ServerReference: can be used by the Client to identify another Server to use.
• AuthenticationMethod: identifier of the Authentication Method.
• AuthenticationData: string containing authentication data.
 
  OnQTTDisconnect: this event is fired when the client is disconnected from MQTT server. Parameters:
ReasonCode: returns code with the result of connection.(New in MQTT 5.0)
ReasonName: text description of ReturnCode.(New in MQTT 5.0)
DisconnectProperties: (New in MQTT 5.0)
 
• SessionExpiryInterval: Session Expiry Interval in seconds.
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client including diagnostic information.
• ServerReference: can be used by the Client to identify another Server to use.
 
  OnMQTTPing: this event is fired when the client receives an acknowledgment from a ping previously sent.
 
  OnMQTTPubAck: this event is fired when receives the response to a Publish Packet with QoS level 1. There is
one parameter:
PacketIdentifier: is packet identifier sent initially.
ReasonCode: returns code with the result of connection.(New in MQTT 5.0)
ReasonName: text description of ReturnCode.(New in MQTT 5.0)
PubAckProperties: (New in MQTT 5.0)
 
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client including diagnostic information.
 
  OnMQTTPubComp: this event is fired when receives the response to a PubRel Packet. It is the fourth and final
packet of the QoS 2 protocol exchange. There are the following parameters:
PacketIdentifier: is packet identifier sent initially.
ReasonCode: returns code with the result of connection.(New in MQTT 5.0)
ReasonName: text description of ReturnCode.(New in MQTT 5.0)
PubCompProperties: (New in MQTT 5.0)
 
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client including diagnostic information.
 
  OnMQTTPublish: this event is fired when the client receives a message from the server. There are 2 parameters:
Topic: is the topic name of the published message.
Text: is the text of the published message.
PublishProperties: (New in MQTT 5.0)
 
• PayloadFormat: select payload format from: mqpfUnspecified (which is equivalent to not sending a
Payload Format Indicator) or mqpfUTF8 (Message s UTF-8 Encoded Character Data).
• MessageExpiryInterval: Length of time after which the server must stop delivery of the publish mes­
sage to a subscriber if not yet processed.
• TopicAlias: is an integer value that is used to identify the Topic instead of using the Topic Name. This
reduces the size of the PUBLISH packet, and is useful when the Topic Names are long and the same
Topic Names are used repetitively within a Network Connection.
• ResponseTopic: is used as the Topic Name for a response message.
• CorrelationData: The Correlation Data is used by the sender of the Request Message to identify
which request the Response Message is for when it is received.
• UserProperties: This property is intended to provide a means of transferring application layer name-
value tags whose meaning and interpretation are known only by the application programs responsible
for sending and receiving them.
• SubscriptionIdentifier: A numeric subscription identifier included in SUBSCRIBE packet which will
be returned with messages delivered for that subscription.
• ContentType: String describing content of message to be sent to all subscribers receiving the mes­
sage.

197
COMPONENTS

 
  OnMQTTPubRec: this event is fired when receives the response to a Publish Packet with QoS 2. It is the second
packet of the QoS 2 protocol exchange. There are the following parameters:
PacketIdentifier: is packet identifier sent initially.
ReasonCode: returns code with the result of connection.(New in MQTT 5.0)
ReasonName: text description of ReturnCode.(New in MQTT 5.0)
PubRecProperties: (New in MQTT 5.0)
 
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client including diagnostic information.
 
  OnMQTTSubscribe: this event is fired as a response to subscribe method. There are the following parameters:
PacketIdentifier: is packet identifier sent initially.
Codes: codes with the result of a subscription.
SubscribeProperties: (New in MQTT 5.0)
 
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client about subscription.
 
 
  OnMQTTUnSubscribe: this event is fired as a response to subscribe method. There are the following parame­
ters:
PacketIdentifier: is packet identifier sent initially.
Codes: codes with the result of a subscription.
UnsubscribeProperties: (New in MQTT 5.0)
 
• UserProperties: provide additional information to the Client about subscription.
 
  OnMQTTAuth: this event is fired as a response to Äuth method. There is one parameter: (New in MQTT 5.0)
ReasonCode: returns code with the result of connection.
ReasonName: text description of ReturnCode.
AuthProperties:
 
• AuthenticationMethod: contains the name of the authentication method used for extended authenti­
cation.
• AuthenticationData: data associated to authentication.
• ReasonString: represents the reason associated with this response. This Reason String is a human
readable string designed for diagnostic.
• UserProperties: provide additional information to the Client including diagnostic information.
 
 
Enhanced Authentication (New in MQTT 5.0)
 
To begin an enhanced authentication, the Client includes an Authentication Method in the ConnectProperties. This
specifies the authentication method to use. If the Server does not support the Authentication Method supplied by
the Client, it may send a Reason Code "Bad authentication method" or Not Authorized.
 
Example:
 
• Client to Server: CONNECT Authentication Method="SCRAM-SHA-1" Authentication Data=client-first-data
• Server to Client: AUTH ReasonCode="Continue authentication" Authentication Method="SCRAM-SHA-1"
Authentication Data=server-first-data
• Client to Server AUTH ReasonCode="Continue authentication" Authentication Method="SCRAM­SHA­1" Au­
thentication Data=client-final-data
• Server to Client CONNACK ReasonCode=0 Authentication Method="SCRAM-SHA-1" Authentication
Data=server-final-data
 

Properties
   MQTTVersion: select which MQTT version (3.1.1 or 5.0) will use to connect to server.
 

198
COMPONENTS

   Authentication: disabled by default, if True a UserName and Password are sent to the server to try user authen­
tication.
 
   HeartBeat: enabled by default, if True, send a ping every X seconds (set by Interval property) to keep alive con­
nection. You can set a Timeout too, so if after X seconds, the client doesn't receive a response to a ping, the con­
nection will be closed automatically.
 
   LastWillTestament: if there is a disconnection and is enabled, a message is sent to all connected clients to in­
form that connection has been closed.
 
• Enabled: enable if you want activate last will testament.
• Text: is the message that the server will publish in the event of an ungraceful disconnection.
• Topic: is the topic that the server will publish the message to in the event of an ungraceful disconnection. Is
mandatory if LastWillTestament is enabled.
• Retain: enable if server must retain message after publish it.
• WillProperties: (New in MQTT 5.0)
• WillDelayInterval: The Server delays publishing the Client’s Will Message until the Will Delay Interval 
has passed or the Session ends, whichever happens first.
• PayloadFormat: select payload format from: mqpfUnspecified (which is equivalent to not sending a
Payload Format Indicator) or mqpfUTF8 (Message s UTF-8 Encoded Character Data).
• MessageExpiryInterval: Length of time after which the server must stop delivery of the will message
to a subscriber if not yet processed.
• ContentType: string describing content of will message.
• ResponseTopic: Used as a topic name for a response message.
• CorrelationData: binary string used by client to identify which request the response message is for
when received.
• UserProperties: can be used to send will related properties from the Client to the Server. The mean­
ing of these properties is not defined by MQTT specification.
 
   ConnectProperties: (New in MQTT 5.0) are connection properties sent with packet connect.
 
• Enabled: if True, connect properties will be sent to server.
• SessionExpiryInterval: if value is zero, session will end when network connection is closed.
• ReceiveMaximum: the Client uses this value to limit the number of QoS 1 and QoS 2 publications that it is
willing to process concurrently.
• MaximumPacketSize: the Client uses the Maximum Packet Size to inform the Server that it will not process
packets exceeding this limit.
• TopicAliasMaximum: the Client uses this value to limit the number of Topic Aliases that it is willing to hold
on this Connection.
• RequestResponseInformation: the Client uses this value to request the Server to return Response Infor­
mation in the CONNACK. If False indicates that the Server MUST NOT return Response Information, If True
the Server MAY return Response Information in the CONNACK packet.
• RequestProblemInformation: the Client uses this value to indicate whether the Reason String or User
Properties are sent in the case of failures. If the value of Request Problem Information is False, the Server
MAY return a Reason String or User Properties on a CONNACK or DISCONNECT packet but MUST NOT
send a Reason String or User Properties on any packet other than PUBLISH, CONNACK, or DISCONNECT.
• UserProperties:  can be used to send connection related properties from the Client to the Server. The 
meaning of these properties is not defined by MQTT specification.
• AuthenticationMethod: contains the name of the authentication method used for extended authentication.
 
 

199
COMPONENTS

TsgcWSPClient_MQTT | Client MQTT Con­
nect
In order to connect to a MQTT Server, you must create first a TsgcWebSocketClient and a TsgcWSPClient_MQTT.
Then you must attach MQTT Component to WebSocket Client.
 

Basic Usage
Connect to Mosquitto MQTT server using websocket protocol. Subscribe to topic: "topic1" after connect.
 

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := 'test.mosquitto.org';
oClient.Port := 8080;
oMQTT := TsgcWSPClient_MQTT.Create(nil);
oMQTT.Client := oClient;
oClient.Active := True;
 
procedure OnMQTTConnect(Connection: TsgcWSConnection; const Session: Boolean; const ReasonCode: Integer;
  const ReasonName: string; const ConnectProperties: TsgcWSMQTTCONNACKProperties);
begin
  oMQTT.Subscribe('topic1');
end;

Client Identifier
MQTT requires a Client Identifier to identify client connection. Component sets a random value automatically but
you can set your own Client Identifier if required, to do this, just handle OnBeforeConnect event and set your val­
ue on aClientIdentifier parameter.
 

procedure OnMQTTBeforeConnect(Connection: TsgcWSConnection; var aCleanSession: Boolean;


  var aClientIdentifier: string);
begin
  aClientIdentifier := 'your client id';
end;

Authentication
Somes servers require an user and password to authorize MQTT connections. Use Authentication property to
set the value for username and password before connect to server.
 

oMQTT := TsgcWSPClient_MQTT.Create(nil);
oMQTT.Authentication.Enabled := True;
oMQTT.Authentication.UserName := 'your user';
oMQTT.Authentication.Password := 'your password';

200
COMPONENTS

TsgcWSPClient_MQTT | Connect MQTT


Mosquitto
Use the following sample configurations to connect to a Mosquitto MQTT Server.

MOSQUITTO MQTT WebSockets

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := 'test.mosquitto.org';
oClient.Port := 8080;
oMQTT := TsgcWSPClient_MQTT.Create(nil);
oMQTT.Client := oClient;
oClient.Active := True;

MOSQUITTO MQTT WebSockets TLS

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := 'test.mosquitto.org';
oClient.Port := 8081;
oClient.TLS := True;
oClient.TLSOptions.Version := tls1_2;
oMQTT := TsgcWSPClient_MQTT.Create(nil);
oMQTT.Client := oClient;
oClient.Active := True;

MOSQUITTO MQTT Plain TCP

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := 'test.mosquitto.org';
oClient.Port := 1883;
oClient.Specifications.RFC6455 := False;
oMQTT := TsgcWSPClient_MQTT.Create(nil);
oMQTT.Client := oClient;
oClient.Active := True;

MOSQUITTO MQTT Plain TCP TLS

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := 'test.mosquitto.org';
oClient.Port := 8083;
oClient.Specifications.RFC6455 := False;
oClient.TLS := True;
oClient.TLSOptions.Version := tls1_2;
oMQTT := TsgcWSPClient_MQTT.Create(nil);
oMQTT.Client := oClient;
oClient.Active := True;

201
COMPONENTS

TsgcWSPClient_MQTT | Client MQTT Ses­
sions
Clean Start
OnMQTTBeforeConnect event, there is a parameter called aCleanSession. If the value of this parameter is True,
means that client want start a new session, so if server has any session stored, it must discard it. So, when On­
MQTTConnect event is fired, aSession parameter will be false. If the value of this parameter is False and there is a
session associated to this client identifier, the server must resume communications with the client on state with the
existing session.
 
So, if client has an unexpected disconnection, and you want to recover the session where was disconnected, in
OnMQTTBeforeConnect set aCleanSession = True and aClientIdentifier = Client ID of Session.
 

Session
Once successful connection, check OnMQTTConnect event, the value of Session parameter.
 
  Session = true, means session has been resumed.
  Session = false, means it's a new session.

 
procedure TfrmWebSocketClient.MQTTMQTTBeforeConnect(Connection: TsgcWSConnection;
  var aCleanSession: Boolean; var aClientIdentifier: string);
begin
  aCleanSession := false;
  aClientIdentifier := 'previous client id';
end;
 
procedure OnMQTTConnect(Connection: TsgcWSConnection; const Session: Boolean;
  const ReasonCode: Integer; const ReasonName: string; const ConnectProperties: TsgcWSMQTTCONNACKProperties);
begin
  if Session then
    WriteLn('Session resumed')
  else
    WriteLn('New Session');
end;

202
COMPONENTS

TsgcWSPClient_MQTT | Client MQTT Ver­
sion
Currently, MQTT Client supports the following specifications:
 
• MQTT 3.1.1: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
• MQTT 5.0: https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html
 
You can select which is the version which will use the MQTT Client component using MQTTVersion property.
 
MQTT 3.1.1: TsgcWSPClient_MQTT.Version = mqtt311
MQTT 5.0: sgcWSPClient_MQTT.Version = mqtt5

203
COMPONENTS

TsgcWSPClient_MQTT | MQTT Publish Sub­
scribe
The publish/subscribe pattern (also known as pub/sub) provides an alternative to traditional client-server architec­
ture. In the client-sever model, a client communicates directly with an endpoint.The pub/sub model decouples the
client that sends a message (the publisher) from the client or clients that receive the messages (the sub­
scribers). The publishers and subscribers never contact each other directly. In fact, they are not even aware that
the other exists. The connection between them is handled by a third component (the broker). The job of the
broker is to filter all incoming messages and distribute them correctly to subscribers.
 
With TsgcWSPClient_MQTT you can Publish messages and Subscribe to Topics.
 

Subscribe Topic
Subscribe to Topic "topic1" after a successful connection.

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := 'test.mosquitto.org';
oClient.Port := 8080;
oMQTT := TsgcWSPClient_MQTT.Create(nil);
oMQTT.Client := oClient;
oClient.Active := True;
 
procedure OnMQTTConnect(Connection: TsgcWSConnection; const Session: Boolean; const ReasonCode: Integer;
  const ReasonName: string; const ConnectProperties: TsgcWSMQTTCONNACKProperties);
begin
  oMQTT.Subscribe('topic1');
end;

Publish Message
Publish a message to all subscribers of "topic1"
 

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := 'test.mosquitto.org';
oClient.Port := 8080;
oMQTT := TsgcWSPClient_MQTT.Create(nil);
oMQTT.Client := oClient;
oClient.Active := True;
 
procedure OnMQTTConnect(Connection: TsgcWSConnection; const Session: Boolean; const ReasonCode: Integer;
  const ReasonName: string; const ConnectProperties: TsgcWSMQTTCONNACKProperties);
begin
  oMQTT.Publish('topic1', 'Hello Subscribers topic1');
end;

204
COMPONENTS

TsgcWSPClient_MQTT | MQTT Topics


Topics
In MQTT, the word topic refers to an UTF-8 string that the broker uses to filter messages for each connected client.
The topic consists of one or more topic levels. Each topic level is separated by a forward slash (topic level separa­
tor)
 
myHome / groundfloor / livingroom / temperature
 
In comparison to a message queue, MQTT topics are very lightweight. The client does not need to create the de­
sired topic before they publish or subscribe to it. The broker accepts each valid topic without any prior initialization.
Note that each topic must contain at least 1 character and that the topic string permits empty spaces. Topics are
case-sensitive.
 
 

WildCards
When a client subscribes to a topic, it can subscribe to the exact topic of a published message or it can use wild­
cards to subscribe to multiple topics simultaneously. A wildcard can only be used to subscribe to topics, not to pub­
lish a message. There are two different kinds of wildcards: _single-level and _multi-level.
 

Single Level: +

As the name suggests, a single-level wildcard replaces one topic level. The plus symbol represents a single-level
wildcard in a topic.
 
myHome / groundfloor / + / temperature
 
Any topic matches a topic with single-level wildcard if it contains an arbitrary string instead of the wildcard. For ex­
ample a subscription to _myhome/groundfloor/+/temperature can produce the following results:
 
YES => myHome / groundfloor / livingroom / temperature
YES => myHome / groundfloor / kitchen / temperature
NO   => myHome / groundfloor / livingroom / brightness
NO   => myHome / firstfloor / livingroom / temperature
NO   => myHome / groundfloor / kitchen / fridge / temperature
 

Multi Level: #

The multi-level wildcard covers many topic levels. The hash symbol represents the multi-level wild card in the topic.
For the broker to determine which topics match, the multi-level wildcard must be placed as the last character in the
topic and preceded by a forward slash.
 
myHome / groundfloor / #
 
YES => myHome / groundfloor / livingroom / temperature
YES => myHome / groundfloor / kitchen / temperature
YES => myHome / groundfloor / kitchen / brightness
NO   => myHome / firstfloor / kitchen / temperature
 
When a client subscribes to a topic with a multi-level wildcard, it receives all messages of a topic that begins with
the pattern before the wildcard character, no matter how long or deep the topic is. If you specify only the multi-level
wildcard as a topic (_#), you receive all messages that are sent to the MQTT broker.
 

205
COMPONENTS

TsgcWSPClient_MQTT | MQTT Subscribe


You can Subscribe to a Topic using method Subscribe from TsgcWSPClient_MQTT. This method has the following
parameters:
 
Topic: is the name of the topic to be subscribed.
QoS: one of the 3 QoS levels (not all brokers support all 3 levels). If not specificed uses mtqsAtMostOnce.
Read more about QoS Levels.
SubscribeProperties: if MQTT 5.0, are additional properties about subscriptions.
 
 

Subscribe QoS = At Least Once

MQTT.Subscribe('topic1', mtqsAtLeastOnce);

Subscribe MQTT 5.0

oProperties := TsgcWSMQTTSubscribe_Properties.Create;
oProperties.SubscriptionIdentifier := 1234;
oProperties.UserProperties.Add('name=value');
 
MQTT.Subscribe('topic1', mtqsAtMostOnce, oProperties);

206
COMPONENTS

TsgcWSPClient_MQTT | MQTT Publish Mes­
sage
You can publish messages to all subscribers of a Topic using Publish method, which has the following parameters:
 
Topic: is the name of the topic where the message will be published.
Text: is the text of the message.
QoS: one of the 3 QoS levels (not all brokers support all 3 levels). If not specificed uses mtqsAtMostOnce.
Read more about QoS Levels.
Retain: if true, this message will be retained. And every time a new client subscribes to this topic, this mes­
sage will be sent to this client.
PublishProperties: if MQTT 5.0, these are the properties of the message.
 

Publish a simple message

MQTT.Publish('topic1', 'Hello Subscribers topic1');

Publish QoS = At Least Once

MQTT.Publish('topic1', 'Hello Subscribers topic1', mtqsAtLeastOnce);

Publish Retained message

MQTT.Publish('topic1', 'Hello Subscribers topic1', mtqsAtMostOnce, true);

207
COMPONENTS

TsgcWSPClient_MQTT | MQTT Receive Mes­
sages
Messages sent by server, are received OnMQTTPublish event. This event has the following parameters:
 
Topic: is the name of the topic associated to this message.
Text: is the text of the message.
PublishProperties: if MQTT 5.0, these are the properties of the published message.
 

Read published Messages

procedure OnMQTTPublish(Connection: TsgcWSConnection; aTopic, aText: string;


  PublishProperties: TsgcWSMQTTPublishProperties);
begin
  WriteLn('Topic: ' + aTopic + '. Message: ' + aText);
end;

208
COMPONENTS

TsgcWSPClient_MQTT | Publish and Wait


Response
MQTT client allows the use of some type of QoS levels, any of those levels works in a different level to be sure that
messages have been processed as expected.
 
There are the following QoS levels:
 
• mtqsAtMostOnce: (by default) the message is delivered according to the best efforts of the un­
derlying TCP/IP network. A response is not expected and no retry semantics are defined in the
protocol. The message arrives at the server either once or not at all.
• mtqsAtLeastOnce: the receipt of a message by the server is acknowledged by an ACKNOWL­
EDGMENT message. If there is an identified failure of either the communications link or the send­
ing device or the acknowledgement message is not received after a specified period of time, the
sender resends the message. The message arrives at the server at least once. A message with
QoS level 1 has an ID param in the message.
• mtqsExactlyOnce: where message are assured to arrive exactly once. This level could be used,
for example, with billing systems where duplicate or lost messages could lead to incorrect charges
being applied. If there is an identified failure of either the communications link or the sending de­
vice, or the acknowledgement message is not received after a specified period of time, the sender
resends the message.
 
You can handle the events OnPubAck or OnPubComp to know if message has been processed by server or you
can use the method PublishAndWait to know if the message has been processed by the server.
The use of PublishAndWait is the same that normal Publish method, now you have a new parameter called Time­
out, where method will return with value false if after certain period of time, there is no response from server. By de­
fault this value is 10 seconds.
 

if mqtt.PublishAndWait('topic', 'text') then


  ShowMessage('Message processed')
else
  ShowMessage('Message error');

209
COMPONENTS

TsgcWSPClient_MQTT | MQTT Clear Re­
tained Messages
By default, every MQTT topic can have a retained message. The standard MQTT mechanism to clean up retained
messages is sending a retained message with an empty payload to a topic. This will remove the retained message.
 

MQTT.Publish('topic1', '', mtqsAtMostOnce, true);

210
COMPONENTS

Protocol AMQP
The Advanced Message Queuing Protocol (AMQP) is an open standard application layer protocol for message-
oriented middleware. The defining features of AMQP are message orientation, queuing, routing (including point-to-
point and publish-and-subscribe), reliability and security.
 
AMQP is a binary, application layer protocol, designed to efficiently support a wide variety of messaging applica­
tions and communication patterns. It provides flow controlled, message-oriented communication with message-de­
livery guarantees such as at-most-once (where each message is delivered once or never), at-least-once (where
each message is certain to be delivered, but may do so multiple times) and exactly-once (where the message will
always certainly arrive and do so only once), and authentication and/or encryption based on SASL and/or TLS. It
assumes an underlying reliable transport layer protocol such as Transmission Control Protocol (TCP).
 

Features
AMQP can be used in any situation if there is a need for high-quality and secure message delivery between client
and broker.
 
AMQP provides the following features:
 
•  Monitoring and sharing updates.
•  Ensuring quick response of the server to requests and transmission of time­consuming tasks for further pro­
cessing.
•  Distribute messages to multiple recipients.
•  Connection offline clients for further data retrieval.
•  Increase the reliability and smooth operation of applications.
•  Reliability of message delivery.
•  High speed message delivery.
•  Message Acceptance.
 

Components
TsgcWSPClient_AMQP: it's the client component that implements AMQP 0.9.1 protocol.
 

Most common uses


• Connection
• Client AMQP Connect
• Client AMQP Disconnect
• Commands
• AMQP Channels
• AMQP Exchanges
• AMQP Queues
• AMQP Publish Messages
• AMQP Consume Messages (Asynchronous)
• AMQP Get Messages (Synchronous)
• AMQP QoS
• AMQP Transactions
 

211
COMPONENTS

TsgcWSPClient_AMQP
The TsgcWSClient_AMQP client implements the full AMQP 0.9.6 protocol following the OASIS specification. The
client supports Plain TCP and WebSocket connections, TLS (secure) connections are supported too.
 

Connection
AMQP 0.9.6 protocols defines the concept of channels, which allows to share a single socket connection with sev­
eral virtual channels, the client implements an internal thread which reads the bytes received and dispatch every
message to the correct channel (which already runs in his own thread), so, if you are running an AMQP connection
with 5 channels, the client will run 6 threads (5 threads which handle the data of every channel and 1 thread which
handles the data of the connection).
 
Before connect to an AMQP server, configure the following properties of the AMQP protocol
 
• AMQPOptions.Locale: it's the message locale to use, it's a negotiated value, so can change when com­
pared with the supported locales supported by the server. The default value is "en_US".
• AMQPOptions.MaxChannels: it's the maximum number of channels which can be opened, it's a negotiated
value, so can change when compared with the server configuration. The default value is 65535.
• AMQPOptions.MaxFrameSize: it's the maximum size in bytes of the AMQP frame, it's a negotiated value,
so can change when compared with the server configuration. The default value is 2147483647.
• AMQPOptions.VirtualHost: it's the name of the virtual host. The default value is "/".
 
The AMQP HeartBeat can be configured too before connect to server, you can enable or disable the use of heart­
beats.
 
• HeartBeat.Enabled: set to true if the client supports HeartBeats.
• HeartBeat.Interval: the desired interval in seconds.
 
Once the AMQP client has been configured, attach to a TsgcWebSocketClient and now you can configure the serv­
er connection properties to connect to the AMQP Server.
Set the property value Specifications.RFC6455 to false if using Plain TCP connection instead of WebSocket con­
nection.
 

oAMQP := TsgcWSPClient_AMQP.Create(nil);
oAMQP.AMQPOptions.Locale := 'en_US';
oAMQP.AMQPOptions.MaxChannels := 100;
oAMQP.AMQPOptions.MaxFrameSize := 16384;
oAMQP.AMQPOptions.VirtualHost := '/';
oAMQP.HeartBeat.Enabled := true;
oAMQP.HeartBeat.Interval := 60;
 
oClient := TsgcWebSocketClient.Create(nil);
oAMQP.Client := oClient;
oClient.Specifications.RFC6455 := false;
oClient.Host := 'www.esegece.com';
oClient.Port := 5672;
oClient.Active := True;

Channels
Once the AMQP client has connected, it can open the first channel.

oAMQP.OpenChannel('channel_name');

212
COMPONENTS

Exchanges
When a Channel is opened, the client can declare new exchanges, verify than exists... use the method DeclareEx­
change to declare a new exchange.
 

oAMQP.DeclareExchange('channel_name', 'exchange_name');

Queues
When a Channel is opened, the client can declare new queues, verify than exists... use the method DeclareQueue
to declare a new Queue. The queues are not provided by default by the server (unlike the exchanges), so it's al­
ways required to declare a new queue (unless a queue has been already created by another client).
 

oAMQP.DeclareQueue('channel_name', 'queue_name');

Binding Queues
Once the Exchanges and Queues are configured, you may need to bind queues to exchanges, this way the ex­
changes can know which messages will be dispatched to the queues.
 
AMQP Servers automatically bind the queues to "direct" exchange using the queue name as routing key. This al­
lows to send a message to a specific queue without the need to declare a binding (just calling PublishMessage
method and pasing the Exchange argument as empty value and the name of the queue in the RoutingKey argu­
ment).
 

oAMQP.BindQueue('channel_name', 'queue_name', 'exchange_name', 'routing_key');

Send Messages
Call the method PublishMessage to publish a new AMQP message. The method allows to publish a String or
TStream message.
 

oAMQP.PublishMessage('channel_name', '', 'queue_name', 'Hello from sgcWebSockets!!!');

Receive Messages
AMQP allows to receive the messages in 2 modes:
 
• Request by Client: using the GetMessage method. If there aren't messages in the queue, the event On­
AMQPBasicGetEmpty will be called.
• Pushed by Server: using the Consume method.
 
Request By Client

oAMQP.GetMessage('channel_name', 'queue_name');
 
procedure OnAMQPGetOk(Sender: TObject; const aChannel: string;
  const aGetOk: TsgcAMQPFramePayload_Method_BasicGetOk; const aContent: TsgcAMQPMessageContent)
begin
  DoLog('#AMQP_basic_GetOk: ' + aChannel + ' ' + IntToStr(aGetOk.MessageCount) + ' ' + aContent.Body.AsString);
end;

Pushed By Server

213
COMPONENTS

oAMQP.Consume('channel_name', 'queue_name');
 
procedure OnAMQPGetOk(Sender: TObject; const aChannel, aConsumerTag: string)
begin
  DoLog('#AMQP_basic_GetOk: ' + aChannel + ' ' + IntToStr(aGetOk.MessageCount) + ' ' + aContent.Body.AsString);
end;

214
COMPONENTS

Connection | Client AMQP Connect


In order to connect to a AMQP Server, you must create first a TsgcWebSocketClient and a TsgcWSPClient_AMQP.
Then you must attach AMQP Component to WebSocket Client.
 

Basic Usage
Connect to AMQP server without authentication. Define the AMQPOptions property values, virtual host and then
set in the TsgcWebSocketClient the Host and Port of the server.
If you are using a TCP Plain connection, set the TsgcWebSocketClient property Specifications.RFC6455 to false.
 

oAMQP := TsgcWSPClient_AMQP.Create(nil);
oAMQP.AMQPOptions.Locale := 'en_US';
oAMQP.AMQPOptions.MaxChannels := 100;
oAMQP.AMQPOptions.MaxFrameSize := 16384;
oAMQP.AMQPOptions.VirtualHost := '/';
oAMQP.HeartBeat.Enabled := true;
oAMQP.HeartBeat.Interval := 60;
 
oClient := TsgcWebSocketClient.Create(nil);
oAMQP.Client := oClient;
oClient.Specifications.RFC6455 := false;
oClient.Host := 'www.esegece.com';
oClient.Port := 5672;
oClient.Active := True;

Authentication
If the server requires authentication, use the event OnAMQPAuthentication to select the Authentication mecha­
nism (if required) and set the User / Password.

oAMQP := TsgcWSPClient_AMQP.Create(nil);
oAMQP.AMQPOptions.Locale := 'en_US';
oAMQP.AMQPOptions.MaxChannels := 100;
oAMQP.AMQPOptions.MaxFrameSize := 16384;
oAMQP.AMQPOptions.VirtualHost := '/';
oAMQP.HeartBeat.Enabled := true;
oAMQP.HeartBeat.Interval := 60;
 
oClient := TsgcWebSocketClient.Create(nil);
oAMQP.Client := oClient;
oClient.Specifications.RFC6455 := false;
oClient.Host := 'www.esegece.com';
oClient.Port := 5672;
oClient.Active := True;
 
procedure OnAMQPAuthentication(Sender: TObject; aMechanisms: TsgcAMQPAuthentications; var Mechanism: TsgcAMQPAuthentication
  var User, Password: string);
begin
  User := 'user_value';
  Password := 'password_value';
end;

215
COMPONENTS

Connection | Client AMQP Disconnect


The client can disconnect a current active connection, using the following methods:
 

Sending a Close Reason


The AMQP client can inform the server that the connection will be closed and provide information about the reason
why is closing the connection. Use the method Close to request a connection close to the server.
 

oAMQP.Close(541, 'Internal Error');

Closing Socket Connection


Just set the property Active of TsgcWebSocketClient to False. You can read more about closing connections.

216
COMPONENTS

Commands | AMQP Channels


AMQP is a multi-channelled protocol. Channels provide a way to multiplex a heavyweight TCP/IP connection into
several light weight connections. This makes the protocol more “firewall friendly” since port usage is predictable. It
also means that traffic shaping and other network QoS features can be easily employed.
 
Every channel run in his own thread, so every time a new message is received, first the client identifies the channel
and queues the message in a queue which is process by the thread channel.
 
The channel life-cycle is this:
 
1. The client opens a new channel (Open).
2. The server confirms that the new channel is ready (Open-Ok).
3. The client and server use the channel as desired.
4. One peer (client or server) closes the channel (Close).
5. The other peer hand-shakes the channel close (Close-Ok).
 

Open Channel
To create a new channel just call the method OpenChannel and pass the channel name as argument. The event
OnAMQPChannelOpen is raised as a confirmation sent by the server that the channel has been opened.

AMQP.OpenChannel('channel_name');
 
procedure OnAMQPChannelOpen(Sender: TObject; const aChannel: string);
begin
  DoLog('#AMQP_channel_open: ' + aChannel);
end;

A Synchronous call can be done too calling the method OpenChannelEx, this method returns true if the channel
has been opened and false if no confirmation from server has arrived.
 

if AMQP.OpenChannelEx('channel_name') then
  DoLog('#AMQP_channel_open: channel_name');
else
  DoLog('#AMQP_Channel_open_error');

Close Channel
To close an existing channel, call the method CloseChannel and pass the channel name as argument. The event
OnAMQPChannelClose will be called when the client receives a confirmation that the channel has been closed.
 
A Synchronous call can be done calling the method CloseChannelEx, this method returns true if the channel has
been closed and false if no confirmation from server has arrived.
 
 

Channel Flow
Flow control is an emergency procedure used to halt the flow of messages from a peer. It works in the same way
between client and server and is implemented by the EnableChannel / DisableChannel commands. Flow control
is the only mechanism that can stop an over-producing publisher.
 
To Disable the Flow of a channel, call the method DisableChannel, the event OnAMQPChannelFlow will be
called when the client receives a confirmation that the channel flow has been disabled.

217
COMPONENTS

The same applies when enabling the flow of a channel, call the method EnableChannel, the event On­
AMQPChannelFlow will be called when the client receives a confirmation that the channel flow has been enabled.
 
Synchronous requests are available through the functions EnableChannelEx and DisableChannelEx.
 
 

218
COMPONENTS

Commands | AMQP Exchanges


The exchange class lets an application manage exchanges on the server. This class lets the application script its
own wiring (rather than relying on some configuration interface). Note: Most applications do not need this level of
sophistication, and legacy middleware is unlikely to be able to support this semantic.
 
The exchange life-cycle is:
 
1. The client asks the server to make sure the exchange exists (Declare). The client can refine this into, "create the
exchange if it does not exist", or "warn me but do not create it, if it does not exist".
2. The client publishes messages to the exchange.
3. The client may choose to delete the exchange (Delete).
 

Declare Exchange
This method creates a new exchanges or verifies that an Exchange already exists. The method has the following
arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• ExchangeName: it's the name of the exchange, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• ExchangeType: it's the exchange type, all AMQP servers support "direct" and "fanout" exchanges. Check
the server documentation to know which exchanges types are supported.
• Passive: if passive is true, the server only verifies that the exchange is already declared. If passive is false,
and the exchange not exists, the server will create a new one.
• Durable: if true, the exchange will be re­created when the server starts. If false, the exchange will be delet­
ed when the server stops.
• AutoDelete: if true, the exchange will be deleted when all queues have been unbound.
• Internal: always false.
• NoWait: if true, the server doesn't sends an acknowledgment to the client.
 
To Declare a new Exchange just call the method DeclareExchange and pass the channel name, exchange name
and exchange type as arguments. The event OnAMQPExchangeDeclare is raised as a confirmation sent by the
server that the exchange has been declared.

AMQP.DeclareExchange('channel_name', 'exchange_name', 'direct');


 
procedure OnAMQPExchangeDeclare(Sender: TObject; const aChannel, aExchange: string);
begin
  DoLog('#AMQP_exchange_declare: [' + aChannel + '] ' + aExchange);
end;

 
A Synchronous call can be done too calling the method DeclareExchangeEx, this method returns true if the Ex­
change has been Declared and false if no confirmation from server has arrived.

if AMQP.DeclareExchangeEx('channel_name', 'exchange_name', 'direct') then


  DoLog('#AMQP_exchange_declare: [' + aChannel + '] ' + aExchange);
else
  DoLog('#AMQP_exchange_declare_error');

Delete Exchange
This method is used to delete an existing Exchange. The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• ExchangeName: it's the name of the exchange, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• IfUnused: the server only deletes the exchange if there aren't any queues bound to it.

219
COMPONENTS

• NoWait: if true, the server doesn't sends an acknowledgment to the client.


 
To Delete an existing Exchange call the method DeleteExchange and pass the channel name and exchange name
as arguments. The event OnAMQPExchangeDelete is raised as a confirmation sent by the server that the ex­
change has been deleted.
 
A Synchronous call can be done too calling the method DeleteExchangeEx, this method returns true if the Ex­
change has been Deleted and false if no confirmation from server has arrived.
 
 

220
COMPONENTS

Commands | AMQP Queues


The queue class lets an application manage message queues on the server. This is a basic step in almost all appli­
cations that consume messages, at least to verify that an expected message queue is actually present.
 
The life-cycle for a durable message queue is fairly simple:
 
1. The client asserts that the message queue exists (Declare, with the "passive" argument).
2. The server confirms that the message queue exists (Declare-Ok).
3. The client reads messages off the message queue.
 
The life-cycle for a temporary message queue is more interesting:
 
1. The client creates the message queue (Declare, often with no message queue name so the server will assign a
name). The server confirms (Declare-Ok).
2. The client starts a consumer on the message queue. The precise functionality of a consumer is defined by the
Basic class.
3. The client cancels the consumer, either explicitly or by closing the channel and/or connection.
4. When the last consumer disappears from the message queue, and after a polite time-out, the server deletes the
message queue.
 
AMQP implements the delivery mechanism for topic subscriptions as message queues. This enables interesting
structures where a subscription can be load balanced among a pool of co-operating subscriber
applications.
 
The life-cycle for a subscription involves an extra bind stage:
 
1. The client creates the message queue (Declare), and the server confirms (Declare-Ok).
2. The client binds the message queue to a topic exchange (Bind) and the server confirms (Bind-Ok).
3. The client uses the message queue as in the previous examples.
 

Declare Queue
This method creates a new queue or verifies that a Queue already exists. The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• QueueName: it's the name of the queue, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• Passive: if passive is true, the server only verifies that the queue is already declared. If passive is false, and
the queue not exists, the server will create a new one.
• Durable: if true, the queue will be re-created when the server starts. If false, the queue will be deleted when
the server stops.
• Exclusive: if true means the queue is only accessed by the current connection.
• AutoDelete: if true, the queue will be deleted when all consumers no longer use the queue.
• NoWait: if true, the server doesn't sends an acknowledgment to the client.
 
To Declare a new Queue just call the method DeclareQueue and pass the channel name and  queue name as ar­
guments. The event OnAMQPQueueDeclare is raised as a confirmation sent by the server that the exchange has
been declared.

AMQP.DeclareQueue('channel_name', 'queue_name');
 
procedure OnAMQPQueueDeclare(Sender: TObject; const aChannel, aQueue: string;
  aMessageCount, aConsumerCount: Integer);
begin
  DoLog('#AMQP_queue_declare: [' + aChannel + '] ' + aQueue);
end;

A Synchronous call can be done too calling the method DeclareQueueEx, this method returns true if the Queue
has been Declared and false if no confirmation from server has arrived.

221
COMPONENTS

if AMQP.DeclareQueueEx('channel_name', 'queue_name') then


  DoLog('#AMQP_queue_declare: [' + aChannel + '] ' + aQueue);
else
  DoLog('#AMQP_queue_declare_error');

Delete Queue
This method is used to delete an existing Queue. The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• QueueName: it's the name of the queue, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• IfUnused: the server only deletes the queue if there aren't any consumers attachedt to it.
• IfEmpty: the server only deletes the queue if there are no messages.
• NoWait: if true, the server doesn't sends an acknowledgment to the client.
 
To Delete an existing Queue call the method DeleteQueue and pass the channel name and queue name as argu­
ments. The event OnAMQPQueueDelete is raised as a confirmation sent by the server that the queue has been
deleted.
 
A Synchronous call can be done too calling the method DeleteQueueEx, this method returns true if the Queue has
been Deleted and false if no confirmation from server has arrived.
 
 

Bind Queue
This method is used to bind a Queue to a Exchange. The Exchanges use the bindings to know which queues will
be used to route the messages.
 
All AMQP Servers bind automatically all the queues to the default exchange (it's a "direct" exchange without name)
using the Queue Name as the binding routing key. This allows to send a message to a specific queue without de­
clare a binding. Just call the method PublishMessage, pass an empty value as Exchange Name and set the Rout­
ingKey with the value of the Queue Name.
 
The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• QueueName: it's the name of the queue, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• ExchangeName: it's the name of the exchange, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• RoutingKey: it's the binding's routing key.
• NoWait: if true, the server doesn't sends an acknowledgment to the client.
 
To Bind a Queue to a Exchange call the method BindQueue and pass the channel name,  queue name, exchange
and routing key as arguments. The event OnAMQPQueueBind is raised as a confirmation sent by the server that
the queue has been bind.

AMQP.BindQueue('channel_name', 'queue_name', 'exchange_name', 'routing_key');


 
procedure OnAMQPQueueBind(Sender: TObject; const aChannel, aQueue, aExchange: string);
begin
  DoLog('#AMQP_queue_bind: [' + aChannel + '] ' + aQueue + ' -->-- ' + aExchange)
end;

 
A Synchronous call can be done too calling the method BindQueueEx, this method returns true if the Queue has
been Bind and false if no confirmation from server has arrived.

if AMQP.BindQueueEx('channel_name', 'queue_name', 'exchange_name', 'routing_key') then


  DoLog('#AMQP_queue_bind: [' + aChannel + '] ' + aQueue + ' --><-- ' + aExchange)

222
COMPONENTS

else
  DoLog('#AMQP_queue_bind_error');

UnBind Queue
This method deletes an existing queue binding.
 
The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• QueueName: it's the name of the queue, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• ExchangeName: it's the name of the exchange, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• RoutingKey: it's the binding's routing key.
 
To UnBind a Queue just call the method UnBindQueue and pass the channel name,  queue name, exchange and
routing key as arguments. The event OnAMQPQueueUnBind is raised as a confirmation sent by the server that
the queue has been unbind.
 
A Synchronous call can be done too calling the method UnBindQueueEx, this method returns true if the Queue
has been UnBind and false if no confirmation from server has arrived.
 

Purge Queue
This method purges all messages of a queue. All the messages that have been sent but are awaiting acknowledg­
ment are not affected.
 
The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• QueueName: it's the name of the queue, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• NoWait: if true, the server doesn't sends an acknowledgment to the client.
 
To Purge a Queue just call the method PurgeQueue and pass the channel name and  queue name as arguments.
The event OnAMQPQueuePurge is raised as a confirmation sent by the server that the queue has been Purged.
 
A Synchronous call can be done too calling the method PurgeQueueEx, this method returns true if the Queue has
been Purged and false if no confirmation from server has arrived.
 

223
COMPONENTS

Commands | AMQP Publish Messages


Publish Messages
The method PublishMessages is used to send a message to the AMQP server.
 
AMQP Servers automatically bind the queues to "direct" exchange using the queue name as routing key. This al­
lows to send a message to a specific queue without the need to declare a binding (just calling PublishMessage
method and pasing the Exchange argument as empty value and the name of the queue in the RoutingKey argu­
ment).
 
The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• ExchangeName: it's the name of the exchange, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• RoutingKey: it's the binding's routing key name.
• Mandatory: if true and the message cannot be routed to any queue, the message is returned by the server, 
the event OnAMQPBasicReturn is fired.
• Immediate: if true and the message cannot be routed to any queue, the message is returned by the server,
the event OnAMQPBasicReturn is fired.
 

AMQP.PublishMessage('channel_name', 'exchange_name', 'routing_key', 'Hello from sgcWebSockets!!!');


 
procedure OnAMQPBasicReturn(Sender: TObject; const aChannel: string;
  const aReturn: TsgcAMQPFramePayload_Method_BasicReturn;
  const aContent: TsgcAMQPMessageContent);
begin
  DoLog('#AMQP_basic_return: ' + aChannel + ' ' + IntToStr(aReturn.ReplyCode) + ' ' + aReturn.ReplyText + ' ' + aContent.Bo
end;

224
COMPONENTS

AMQP Consume Messages


Consumers consume from queues. In order to consume messages there has to be a queue. When a new con­
sumer is added, assuming there are already messages ready in the queue, deliveries will start immediately.
The target queue can be empty at the time of consumer registration. In that case first deliveries will happen
when new messages are enqueued.
 
Consuming messages is an asynchronous task, which means that every time a new message can be delivered
to the consumer queue, it's pushed by the server to the client automatically. You can read an alternative method
to Receive Message Synchronously.
 

Consume
The method Consume creates a new consumer in the queue, and every time there is a new message this will
be delivered automatically to the consumer client.
 
The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• QueueName: it's the name of the queue, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• ConsumerTag: it's the name of the consumer and must be unique. If it's not set, then the server creates a
new one.
• NoLocal: if true means the consumer never consumes messages published on the same channel.
• NoAck: if true means the server doesn't expect an acknowledgment for every message delivered.
• Exclusive: if true prevents that other consumers consume messages from this queue.
• NoWait: if true, the server won't send an acknowledgment to the client.
 
The messages are delivered OnAMQPBasigGetOk event.
 

AMQP.Consume('channel_name', 'exchange_name', 'consumer_tag');


 
procedure OnAMQPBasicGetOk(Sender: TObject; const aChannel: string;
  const aGetOk: TsgcAMQPFramePayload_Method_BasicGetOk;
  const aContent: TsgcAMQPMessageContent);
begin
  DoLog('#AMQP_basic_GetOk: ' + aChannel + ' ' + IntToStr(aGetOk.MessageCount) + ' ' + aContent.Body.AsString);
end;

A Synchronous call can be done just calling the method ConsumeEx, this method returns true if the Consumer has
been created and false if no confirmation from server has arrived.
 

Cancel Consume
This method is used to Cancel an existing consumer queue.
 
The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• ConsumerTag: it's the name of the consumer.
• NoWait: if true, the server won't send an acknowledgment to the client.
 

AMQP.CancelConsume('channel_name', 'consumer_tag');
 
procedure OnAMQPBasicCancelConsume(Sender: TObject; const aChannel: string; const aConsumerTag);
begin

225
COMPONENTS

  DoLog('#AMQP_basic_cancel_consume: ' + aChannel + ' ' + aConsumerTag);


end;

A Synchronous call can be done just calling the method CancelConsumeEx, this method returns true if the Con­
sumer has been cancelled and false if no confirmation from server has arrived.
 

226
COMPONENTS

Commands | AMQP Get Messages


Getting messages is a Synchronous task, which means that is the client who ask to server is there are mes­
sages in the queue. You can read an alternative method to Receive Message Aynchronously.
 

Get Message
The method GetMessage sends a request to the AMQP server asking if there are messages available in a
queue. If there are messages these will be dispatched OnAMQPBasicGetOk event and if the queue is empty,
the event OnAMQPBasicGetEmpty will be called.
 
The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• QueueName: it's the name of the queue, must be no longer of 255 characters and not begin with
"amq." (except if passive parameter is true).
• NoWait: if true, the server won't send an acknowledgment to the client.
 

AMQP.GetMessage('channel_name', 'exchange_name');
 
procedure OnAMQPBasicGetOk(Sender: TObject; const aChannel: string;
  const aGetOk: TsgcAMQPFramePayload_Method_BasicGetOk;
  const aContent: TsgcAMQPMessageContent);
begin
  DoLog('#AMQP_basic_GetOk: ' + aChannel + ' ' + IntToStr(aGetOk.MessageCount) + ' ' + aContent.Body.AsString);
end;
 
procedure OnAMQPBasicGetEmpty(Sender: TObject; const aChannel: string);
begin
  DoLog('#AMQP_basic_GetEmpty: ' + aChannel);
end;

A Synchronous call can be done just calling the method GetMessageEx, this method returns true if the queue has
messages available, otherwise the result will be false.
 
 

227
COMPONENTS

Commands | AMQP QoS


AMQP allows to set a QoS level to limit the number of messages the server sends to the client before wait to get
the acknowledgment of the messages.
 

Set QoS
The method SetQoS is used to limit the number messages the server sends to the AMQP client.
The method has the following arguments:
 
• ChannelName: it's the name of the channel (must be open before call this method).
• PrefetchSize: it's the windows size in bytes, the server doesn't send messages to the client if the total size
of all currently unacknowledged messages already sent plus the next message to be sent it's greater than
PrefetchSize argument. If the value is zero, means no limit.
• PrefetchCount: is the maximum number of unacknowledged messages already sent and not acknowl­
edged, if the number is greater, the server stops sending messages to the client.
• Global: if true the QoS applies to all existing and new consumers of the connection. If false, the QoS applies
to all existing and new consumers of the channel.
 
The response from the server is received OnAMQPBasicQoS event.

AMQP.SetQoS('channel_name', 1024000, 100, false);


 
procedure OnAMQPBasicQoS(Sender: TObject; const aChannel: string;
  const aQoS: TsgcAMQPFramePayload_Method_BasicQoS);
begin
  DoLog('#AMQP_basic_qos: ' + aChannel + ' ' + IntToStr(aQoS.PrefetchSize) + ' '
    + IntToStr(aQoS.PrefetchCount) + ' ' + BoolToStr(aQoS.Global));
end;

 
A Synchronous call can be done just calling the method SetQoSEx, this method returns true if the request has
been processed, otherwise the result will be false.
 
 
 

228
COMPONENTS

Commands | AMQP Transactions


AMQP supports two kinds of transactions:
 
1. Automatic transactions, in which every published message and acknowledgement is processed as a stand-alone
transaction.
2. Server local transactions, in which the server will buffer published messages and acknowledgements and com­
mit them on demand from the client.
 
The Transaction class (“tx”) gives applications access to the second type, namely server transactions. The seman­
tics of this class are:
 
1. The application asks for server transactions in each channel where it wants these transactions (Select).
2. The application does work (Publish, Ack).
3. The application commits or rolls-back the work (Commit, Roll-back).
4. The application does work, ad infinitum.
 
Transactions cover published contents and acknowledgements, not deliveries. Thus, a rollback does not requeue
or redeliver any messages, and a client is entitled to acknowledge these messages in a following transaction.
 
The Transaction methods allows publish and ack operations to be batched into atomic units of work. The intention
is that all publish and ack requests issued within a transaction will complete successfully or none of them will.

Start Transaction
The method StartTransaction starts a new transaction in the server, the client uses this method at least once on a
channel before using the Commit or Rollback methods. The event OnAMQPTransactionOk is raised when the
server acknowledges the use of transactions.

AMQP.StartTransaction('channel_name');
 
procedure OnAMQPTransactionOk(Sender: TObject; const aChannel: string; aTransaction: TsgcAMQPTransaction);
begin
  case aTransaction of
    amqpTransactionSelect:
      DoLog('#AMQP_transaction_ok: [' + aChannel + '] select');
    amqpTransactionCommit:
      DoLog('#AMQP_transaction_ok: [' + aChannel + '] commit');
    amqpTransactionRollback:
      DoLog('#AMQP_transaction_ok: [' + aChannel + '] rollback');
  end;
end;

A Synchronous call can be done just calling the method StartTransactionEx, this method returns true if the re­
quest has been processed, otherwise the result will be false.

Commit Transaction
This method commits all message publications and acknowledgments performed in the current transaction. A new
transaction starts immediately after a commit. The event OnAMQPTransactionOk is raised when the server ac­
knowledges the use of transactions.

AMQP.CommitTransaction('channel_name');

A Synchronous call can be done just calling the method CommitTansactionEx, this method returns true if the re­
quest has been processed, otherwise the result will be false.

229
COMPONENTS

Rollback Transaction
This method abandons all message publications and acknowledgments performed in the current transaction. A new
transaction starts immediately after a rollback. Note that unacked messages will not be automatically redelivered by
rollback; if that is required an explicit recover call should be issued. The event OnAMQPTransactionOk is raised
when the server acknowledges the use of transactions.

AMQP.RollbackTransaction('channel_name');

A Synchronous call can be done just calling the method RollbackTransactionEx, this method returns true if the re­
quest has been processed, otherwise the result will be false.
 

230
COMPONENTS

Protocol STOMP
STOMP is the Simple (or Streaming) Text Orientated Messaging Protocol. STOMP provides an interoperable wire
format so that STOMP clients can communicate with any STOMP message broker to provide easy and widespread
messaging interoperability among many languages, platforms and brokers.
 
Our STOMP client components support following STOMP versions: 1.0, 1.1 and 1.2.
 

Components
  TsgcWSPClient_STOMP: generic STOMP Protocol client, allows to connect to any STOMP Server.
 
  TsgcWSPClient_STOMP_RabbitMQ: STOMP client for RabbitMQ Broker.
 
  TsgcWSPClient_STOMP_ActiveMQ: STOMP client for ActiveMQ Broker.
 
 
 

231
COMPONENTS

TsgcWSPClient_STOMP
This is Client Protocol STOMP Component, you need to drop this component in the form and select a TsgcWeb­
SocketClient Component using Client Property.
 

Methods
  Send: The SEND frame sends a message to a destination in the messaging system.
 
  Subscribe: The SUBSCRIBE frame is used to register to listen to a given destination.
 
  UnSubscribe: The UNSUBSCRIBE frame is used to remove an existing subscription.
 
  ACK: ACK is used to acknowledge the consumption of a message from a subscription.
 
  NACK: NACK is the opposite of ACK. It is used to tell the server that the client did not consume the message.
 
  BeginTransaction: is used to start a transaction. Transactions in this case apply to sending and acknowledging -
any messages sent or acknowledged during a transaction will be processed atomically based on the transaction.
 
  CommitTransaction: is used to commit a transaction in progress.
 
  AbortTransaction: is used to roll back a transaction in progress.
 
  Disconnect: use to graceful shutdown connection, where the client is assured that all previous frames have been
received by the server.
 
 

Events
  OnSTOMPConnected: this event is fired after a new connection is established.
version : The version of the STOMP protocol the session will be using. See Protocol Negotiation for more
details.
STOMP 1.2 servers MAY set the following headers:
  heart-beat : The Heart-beating settings.
  session : A session identifier that uniquely identifies the session.
  server : A field that contains information about the STOMP server. The field MUST contain a server-name
field and MAY be followed by optional comment fields delimited by a space character.
 
  OnSTOMPMessage: this event is fired when the client receives a message.
The MESSAGE frame MUST include a destination header indicating the destination the message was sent
to. If the message has been sent using STOMP, this destination header SHOULD be identical to the one
used in the corresponding SEND frame.
The MESSAGE frame MUST also contain a message-id header with a unique identifier for that message
and a subscription header matching the identifier of the subscription that is receiving the message.
If the message is received from a subscription that requires explicit acknowledgment (either client or client-
individual mode) then the MESSAGE frame MUST also contain an ack header with an arbitrary value. This
header will be used to relate the message to a subsequent ACK or NACK frame.
MESSAGE frames SHOULD include a content-length header and a content-type header if a body is present.
MESSAGE frames will also include all user-defined headers that were present when the message was sent
to the destination in addition to the server-specific headers that MAY get added to the frame.
 
  OnSTOMPReceipt: this event is fired once a server has successfully processed a client frame that requests a re­
ceipt.
A RECEIPT frame is an acknowledgment that the corresponding client frame has been processed by the
server. Since STOMP is stream based, the receipt is also a cumulative acknowledgment that all the previous
frames have been received by the server. However, these previous frames may not yet be fully processed. If
the client disconnects, previously received frames SHOULD continue to get processed by the server.

232
COMPONENTS

 
  OnSTOMPError: this event is fired if something goes wrong.
The ERROR frame SHOULD contain a message header with a short description of the error, and the body
MAY contain more detailed information (or MAY be empty).
If the error is related to a specific frame sent from the client, the server SHOULD add additional headers to
help identify the original frame that caused the error. For example, if the frame included a receipt header, the
ERROR frame SHOULD set the receipt-id header to match the value of the receipt header of the frame
which the error is related to.
ERROR frames SHOULD include a content-length header and a content-type header if a body is present.
 
 

Properties
   Authentication: disabled by default, if True a UserName and Password are sent to the server to try user authen­
tication.
 
   HeartBeat: Heart-beating can optionally be used to test the healthiness of the underlying TCP connection and to
make sure that the remote end is alive and kicking. In order to enable heart-beating, each party has to declare what
it can do and what it would like the other party to do. 0 means it cannot send/receive heart-beats, otherwise it is the
desired number of milliseconds between heart-beats.
 
   Options: The name of a virtual host that the client wishes to connect to. It is recommended clients set this to the
host name that the socket was established against, or to any name of their choosing. If this header does not match
a known virtual host, servers supporting virtual hosting MAY select a default virtual host or reject the connection.
 
   Versions: Set which STOMP versions are supported.
 
   ConnectHeaders: Allows to send custom headers when CONNECT method is sent.
 

233
COMPONENTS

TsgcWSPClient_STOMP_RabbitMQ
This is Client Protocol STOMP Component for RabbitMQ Broker, you need to drop this component in the form and
select a TsgcWebSocketClient Component using Client Property.
 

Destinations
The STOMP specification does not prescribe what kinds of destinations a broker must support, instead the value of
the destination header in SEND and MESSAGE frames is broker-specific. The RabbitMQ STOMP adapter supports
a number of different destination types:
 
• Topic: SEND and SUBSCRIBE to transient and durable topics.
• Queue: SEND and SUBSCRIBE to queues managed by the STOMP gateway.
• QueueOutside: SEND and SUBSCRIBE to queues created outside the STOMP gateway.
• TemporaryQueue: create temporary queues (in reply-to headers only).
• Exchange: SEND to arbitrary routing keys and SUBSCRIBE to arbitrary binding patterns.
 

Methods
  Publish: The SEND frame sends a message to a destination in the messaging system.
PublishTopic
PublishQueue
PublishQueueOutside
PublishTemporaryQueue
PublishExchange
 
  Subscribe: The SUBSCRIBE frame is used to register to listen to a given destination. Supports following sub­
scriptions
SubscribeTopic
SubscribeQueue
SubscribeQueueOutside
SubscribeTemporaryQueue
SubscribeExchange
 
  UnSubscribe: The UNSUBSCRIBE frame is used to remove an existing subscription. Supports following UnSub­
scriptions
UnSubscribeTopic
UnSubscribeQueue
UnSubscribeQueueOutside
UnSubscribeTemporaryQueue
UnSubscribeExchange
 
  ACK: ACK is used to acknowledge the consumption of a message from a subscription.
 
  NACK: NACK is the opposite of ACK. It is used to tell the server that the client did not consume the message.
 
  BeginTransaction: is used to start a transaction. Transactions in this case apply to sending and acknowledging -
any messages sent or acknowledged during a transaction will be processed atomically based on the transaction.
 
  CommitTransaction: is used to commit a transaction in progress.
 
  AbortTransaction: is used to roll back a transaction in progress.
 
  Disconnect: use to graceful shutdown connection, where the client is assured that all previous frames have been
received by the server.
 
 

234
COMPONENTS

Events
  OnRabbitMQConnected: this event is fired after a new connection is established.
version : The version of the STOMP protocol the session will be using. See Protocol Negotiation for more
details.
STOMP 1.2 servers MAY set the following headers:
  heart-beat : The Heart-beating settings.
  session : A session identifier that uniquely identifies the session.
  server : A field that contains information about the STOMP server. The field MUST contain a server-name
field and MAY be followed by optional comment fields delimited by a space character.
 
  OnRabbitMQMessage: this event is fired when the client receives a message.
The MESSAGE frame MUST include a destination header indicating the destination the message was sent
to. If the message has been sent using STOMP, this destination header SHOULD be identical to the one
used in the corresponding SEND frame.
The MESSAGE frame MUST also contain a message-id header with a unique identifier for that message
and a subscription header matching the identifier of the subscription that is receiving the message.
If the message is received from a subscription that requires explicit acknowledgment (either client or client-
individual mode) then the MESSAGE frame MUST also contain an ack header with an arbitrary value. This
header will be used to relate the message to a subsequent ACK or NACK frame.
MESSAGE frames SHOULD include a content-length header and a content-type header if a body is present.
MESSAGE frames will also include all user-defined headers that were present when the message was sent
to the destination in addition to the server-specific headers that MAY get added to the frame.
 
  OnRabbitMQReceipt: this event is fired once a server has successfully processed a client frame that requests a
receipt.
A RECEIPT frame is an acknowledgment that the corresponding client frame has been processed by the
server. Since STOMP is stream based, the receipt is also a cumulative acknowledgment that all the previous
frames have been received by the server. However, these previous frames may not yet be fully processed. If
the client disconnects, previously received frames SHOULD continue to get processed by the server.
 
  OnRabbitMQError: this event is fired if something goes wrong.
The ERROR frame SHOULD contain a message header with a short description of the error, and the body
MAY contain more detailed information (or MAY be empty).
If the error is related to a specific frame sent from the client, the server SHOULD add additional headers to
help identify the original frame that caused the error. For example, if the frame included a receipt header, the
ERROR frame SHOULD set the receipt-id header to match the value of the receipt header of the frame
which the error is related to.
ERROR frames SHOULD include a content-length header and a content-type header if a body is present.
 
 

Properties
   Authentication: disabled by default, if True a UserName and Password are sent to the server to try user authen­
tication.
 
   HeartBeat: Heart-beating can optionally be used to test the healthiness of the underlying TCP connection and to
make sure that the remote end is alive and kicking. In order to enable heart-beating, each party has to declare what
it can do and what it would like the other party to do. 0 means it cannot send/receive heart-beats, otherwise it is the
desired number of milliseconds between heart-beats.
 
   Options: The name of a virtual host that the client wishes to connect to. It is recommended clients set this to the
host name that the socket was established against, or to any name of their choosing. If this header does not match
a known virtual host, servers supporting virtual hosting MAY select a default virtual host or reject the connection.
 
   Versions: Set which STOMP versions are supported.

235
COMPONENTS

TsgcWSPClient_STOMP_ActiveMQ
This is Client Protocol STOMP Component for ActiveMQ Broker, you need to drop this component in the form and
select a TsgcWebSocketClient Component using Client Property.
 

Destinations
The STOMP specification does not prescribe what kinds of destinations a broker must support, instead the value of
the destination header in SEND and MESSAGE frames is broker-specific. The Active STOMP adapter supports a
number of different destination types:
 
• Topic: SEND and SUBSCRIBE to transient and durable topics.
• Queue: SEND and SUBSCRIBE to queues managed by the STOMP gateway.
 
 

Publish Options
Note that STOMP is designed to be as simple as possible - so any scripting language/platform can message any
other with minimal effort. STOMP allows pluggable headers on each request such as sending & receiving mes­
sages. ActiveMQ has several extensions to the Stomp protocol, so that JMS semantics can be supported by Stomp
clients. An OpenWire JMS producer can send messages to a Stomp consumer, and a Stomp producer can send
messages to an OpenWire JMS consumer. And Stomp to Stomp configurations, can use the richer JMS message
control.
 
STOMP supports the following standard JMS properties on SENT messages:
 
• CorrelationId: Good consumers will add this header to any responses they send.
• Expires: Expiration time of the message.
• JMSXGroupID: Specifies the Message Groups.
• JMSXGroupSeq: Optional header that specifies the sequence number in the Message Groups.
• Persistent: Whether or not the message is persistent.
• Priority: Priority on the message.
• ReplyTo: Destination you should send replies to.
• MsgType: Type of the message.
 
 
 

Methods
  Publish: The SEND frame sends a message to a destination in the messaging system.
PublishTopic
PublishQueue
 
  Subscribe: The SUBSCRIBE frame is used to register to listen to a given destination. Supports following sub­
scriptions
SubscribeTopic
SubscribeQueue
 
  UnSubscribe: The UNSUBSCRIBE frame is used to remove an existing subscription. Supports following UnSub­
scriptions
UnSubscribeTopic
UnSubscribeQueue
 
  ACK: ACK is used to acknowledge the consumption of a message from a subscription.
 
  NACK: NACK is the opposite of ACK. It is used to tell the server that the client did not consume the message.

236
COMPONENTS

 
  BeginTransaction: is used to start a transaction. Transactions in this case apply to sending and acknowledging -
any messages sent or acknowledged during a transaction will be processed atomically based on the transaction.
 
  CommitTransaction: is used to commit a transaction in progress.
 
  AbortTransaction: is used to roll back a transaction in progress.
 
  Disconnect: use to graceful shutdown connection, where the client is assured that all previous frames have been
received by the server.
 
 

Events
  OnActiveMQConnected: this event is fired after a new connection is established.
version : The version of the STOMP protocol the session will be using. See Protocol Negotiation for more
details.
STOMP 1.2 servers MAY set the following headers:
  heart-beat : The Heart-beating settings.
  session : A session identifier that uniquely identifies the session.
  server : A field that contains information about the STOMP server. The field MUST contain a server-name
field and MAY be followed by optional comment fields delimited by a space character.
 
  OnActiveMQMessage: this event is fired when the client receives a message.
The MESSAGE frame MUST include a destination header indicating the destination the message was sent
to. If the message has been sent using STOMP, this destination header SHOULD be identical to the one
used in the corresponding SEND frame.
The MESSAGE frame MUST also contain a message-id header with a unique identifier for that message
and a subscription header matching the identifier of the subscription that is receiving the message.
If the message is received from a subscription that requires explicit acknowledgment (either client or client-
individual mode) then the MESSAGE frame MUST also contain an ack header with an arbitrary value. This
header will be used to relate the message to a subsequent ACK or NACK frame.
MESSAGE frames SHOULD include a content-length header and a content-type header if a body is present.
MESSAGE frames will also include all user-defined headers that were present when the message was sent
to the destination in addition to the server-specific headers that MAY get added to the frame.
 
  OnActiveMQReceipt: this event is fired once a server has successfully processed a client frame that requests a
receipt.
A RECEIPT frame is an acknowledgment that the corresponding client frame has been processed by the
server. Since STOMP is stream based, the receipt is also a cumulative acknowledgment that all the previous
frames have been received by the server. However, these previous frames may not yet be fully processed. If
the client disconnects, previously received frames SHOULD continue to get processed by the server.
 
  OnActiveMQError: this event is fired if something goes wrong.
The ERROR frame SHOULD contain a message header with a short description of the error, and the body
MAY contain more detailed information (or MAY be empty).
If the error is related to a specific frame sent from the client, the server SHOULD add additional headers to
help identify the original frame that caused the error. For example, if the frame included a receipt header, the
ERROR frame SHOULD set the receipt-id header to match the value of the receipt header of the frame
which the error is related to.
ERROR frames SHOULD include a content-length header and a content-type header if a body is present.
 
 

Properties
   Authentication: disabled by default, if True a UserName and Password are sent to the server to try user authen­
tication.
 
   HeartBeat: Heart-beating can optionally be used to test the healthiness of the underlying TCP connection and to
make sure that the remote end is alive and kicking. In order to enable heart-beating, each party has to declare what
it can do and what it would like the other party to do. 0 means it cannot send/receive heart-beats, otherwise it is the
desired number of milliseconds between heart-beats.

237
COMPONENTS

 
   Options: The name of a virtual host that the client wishes to connect to. It is recommended clients set this to the
host name that the socket was established against, or to any name of their choosing. If this header does not match
a known virtual host, servers supporting virtual hosting MAY select a default virtual host or reject the connection.
 
   Versions: Set which STOMP versions are supported.

238
COMPONENTS

Protocol AppRTC
WebRTC (Web Real-Time Communication) is an API definition being drafted by the World Wide Web Consortium
(W3C) to enable browser to browser applications for voice calling, video chat and P2P file sharing without plugins.
The RTC in WebRTC stands for Real-Time Communications, a technology that enables audio/video streaming and
data sharing between browser clients (peers). As a set of standards, WebRTC provides any browser with the ability
to share application data and perform teleconferencing peer to peer, without the need to install plug-ins or third-par­
ty software.
 
WebRTC components are accessed with JavaScript APIs. Currently, in development are the Network Stream API,
which represents an audio or video data stream, and the PeerConnection API, which allows two or more users to
communicate browser-to-browser. Also under development is a DataChannel API that enables communication of
other types of data for real-time gaming, text chat, file transfer, and so forth.
 
appr.tc is a WebRTC demo application developed by Google and Mozilla, it enables both browsers to “talk” to each
other using the WebRTC API.

Components
  TsgcWSPServer_AppRTC: Server Protocol AppRTC VCL Component.

239
COMPONENTS

TsgcWSPServer_AppRTC
This is Server Protocol AppRTC Component, you need to drop this component in the form and select a TsgcWeb­
SocketServer Component using Server Property.
 

Parameters
• IceServers: here you can configure turn/stun servers for WebRTC connections.
• RoomLink: URL base to access room. Example: https://mydemo.com/r/
• WebSocketURL: URL to WebSocket server. Example: wss://mydemo.com
 
WebRTC Protocol requires STUN/TURN server, demos use public STUN/TURN servers for testing purposes. In or­
der to put in a production system, a dedicated STUN/TURN server is required.
Registered users can download compiled binaries of Coturn server for Windows. Read more about COTURN
STUN/TURN.
 
IceServers Configuration
 
If you are running your STUN/TURN server in the following IP Address: 51.122.4.88 and is listening port 3478. User
to connect is "apprtc" and credential is "secret". Configure the IceServers as follows:
 

{
"lifetimeDuration": "86400s",
"iceServers": [{
"urls": "stun:51.122.4.88:3478",
"username": "apprtc",
"credential": "secret"
}, {
"urls": "turn:51.122.4.88:3478",
"username": "apprtc",
"credential": "secret"
}],
"blockStatus": "NOT_BLOCKED",
"iceTransportPolicy": "all"
}

240
COMPONENTS

Protocol WebRTC
WebRTC (Web Real-Time Communication) is an API definition being drafted by the World Wide Web Consortium
(W3C) to enable the browser to browser applications for voice calling, video chat and P2P file sharing without plug­
ins. The RTC in WebRTC stands for Real-Time Communications, a technology that enables audio/video streaming
and data sharing between browser clients (peers). As a set of standards, WebRTC provides any browser with the
ability to share application data and perform teleconferencing peer to peer, without the need to install plug-ins or
third-party software.
 
WebRTC components are accessed with JavaScript APIs. Currently, in development are the Network Stream API,
which represents an audio or video data stream, and the PeerConnection API, which allows two or more users to
communicate browser-to-browser. Also under development is a DataChannel API that enables communication of
other types of data for real-time gaming, text chat, file transfer, and so forth.
 

Components
  TsgcWSPServer_WebRTC: Server Protocol WebRTC VCL Component.
 
 

Parameters
• IceServers: here you can configure turn/stun servers for WebRTC connections. By default uses the follow­
ing public STUN servers
 
{"iceServers": [{"url": "stun:stun.l.google.com:19302"}]}
 

Browser Test
If you want to test this protocol with your favourite Web Browser, please type this url (you need to define your cus­
tom host and port)
 
  http://host:port/webrtc.esegece.com.html

241
COMPONENTS

TsgcWSPServer_WebRTC
This is Server Protocol WebRTC Component, you need to drop this component in the form and select a TsgcWeb­
SocketServer Component using Server Property.
 
WebRTC Protocol requires STUN/TURN server, demos use public STUN/TURN servers for testing purposes. In or­
der to put in a production system, a dedicated STUN/TURN server is required.
 
Registered users can download compiled binaries of Coturn server for Windows. Read more about COTURN
STUN/TURN.

242
COMPONENTS

Protocol WebRTC Javascript


Here you can find available methods, you need to replace {%host%} and {%port%} variables as needed, example:
if you have configured your sgcWebSocket server to listen port 80 on www.example.com website you need to con­
figure:
 

<script src="http://www.example.com:80/sgcWebSockets.js"></script>
<script src="http://www.example.com:80/webrtc.esegece.com.js"></script>

 
 

Open Connection
When a WebSocket connection is opened, browser request access to local camera and microphone,
you need to allow access.
 

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/webrtc.esegece.com.js"></script>
<script>
  var socket = new sgcws_webrtc('ws://{%host%}:{%port%}');
</script>

 
 
 

Open WebRTC Channel


When a browser has access to local camera and microphone, 'sgcmediastart' event is fired and then
you can try to connect to another client using webrtc_connect procedure
 
 

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/webrtc.esegece.com.js"></script>
<script>
  var socket = new sgcws_webrtc('ws://{%host%}:{%port%}');
  socket.on('sgcmediastart', function(event)
  {  
    socket.webrtc_connect('custom channel');
  }
</script>

 
 
 

Close WebRTC channel

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/webrtc.esegece.com.js"></script>
<script>
  socket.webrtc_disconnect('custom channel');
</script>

 
 

243
COMPONENTS

Protocol WAMP
WAMP is an open WebSocket subprotocol that provides two asynchronous messaging patterns: RPC and PubSub.
 
Technically, WAMP is an officially registered WebSocket subprotocol (runs on top of WebSocket) that uses JSON
as message serialization format.
 
What is RPC?
 
Remote Procedure Call (RPC) is a messaging pattern involving peers to two roles: client and server.
A server provides methods or procedure to call under well-known endpoints.
A client calls remote methods or procedures by providing the method or procedure endpoint and any arguments for
the call.
The server will execute the method or procedure using the supplied arguments to the call and return the result of
the call to the client.
 
What is PubSub?
 
Publish & Subscribe (PubSub) is a messaging pattern involving peers of three roles: publisher, subscriber and bro­
ker.
A publisher sends (publishes) an event by providing a topic (aka channel) as the abstract address, not a specific
peer.
A subscriber receives events by first providing topics (aka channels) he is interested. Subsequently, the subscriber
will receive any events publishes to that topic.
The broker sits between publishers and subscribers and mediates messages publishes to subscribers. A broker will
maintain lists of subscribers per topic so it can dispatch new published events to the appropriate subscribers.
A broker may also dispatch events on its own, for example when the broker also acts as an RPC server and a
method executed on the server should trigger a PubSub event.
In summary, PubSub decouples publishers and receivers via an intermediary, the broker.
 
 

Components
  TsgcWSPServer_WAMP: Server Protocol WAMP VCL Component.
 
  TsgcWSPClient_WAMP: Client Protocol WAMP VCL Component.
 
  Javascript Component: Client Javascript Reference.
 
 

Most Common Uses


• RPC
• Simple RPC
• RPC Progress Results
• PubSub
• Subscribers
• Publishers
 

Browser Test
If you want to test this protocol with your favourite Web Browser, please type this URL(you need to define your cus­
tom host and port)
 
  http://host:port/wamp.esegece.com.html

244
COMPONENTS

TsgcWSPServer_WAMP
This is Server Protocol WAMP Component, you need to drop this component in the form and select a TsgcWeb­
SocketServer Component using Server Property.
 

Methods
  CallResult: When the execution of the remote procedure finishes successfully, the server responds by sending a
message with the result.
 
• CallId: this is the ID generated by client when request a call to a procedure
• Result: is the result, can be a number, a JSON object...
 
  CallProgressResult: when rpc has multiple results, this method is called when still there are more results to
send. Example: if method has 20 results, from method 1 to 19, CallProgressResult must be called. And the final
method, number 20, must be called with CallResult to finish method.
 
• CallId: this is the ID generated by client when request a call to a procedure
• Result: is the result, can be a number, a JSON object...
 
  CallError: When the remote procedure call could not be executed, an error or exception occurred during the exe­
cution or the execution of the remote procedure finishes unsuccessfully for any other reason, the server responds
by sending a message with error details.
 
• CallId: this is the ID generated by the client when requesting a call to a procedure
• ErrorURI: identifies the error.
• ErrorDesc: error description.
• ErrorDetails: application error details, is optional.
 
 
  Event: Subscribers receive PubSub events published by subscribers via the EVENT message.
 
• TopicURI: channel name where is subscribed.
• Event: message text.
 

Events
  OnCall: event fired when the server receives RPC called by the client
 
• CallId: this is the ID generated by the client when requesting a call to a procedure
• ProcUri: procedure identifier...
• Arguments: procedure params, can be a integer, a JSON object, a list...
 
  OnBeforeCancelCall: event fired when the server receives a request to cancel a Call from client.
 
• CallId: this is the ID generated by the client when requesting a call to a procedure
• Cancel: by default is True, which means that Call will be cancelled. If server doesn't want cancel this
call, set this parameter to false.
 
  OnPrefix: Procedures and Errors are identified using URIs or CURIEs, this event is fired when a client sends a
new prefix
 
• Prefix: compact URI expression.
• URI: full URI.
 

245
COMPONENTS

 
 

246
COMPONENTS

TsgcWSPClient_WAMP
This is Client Protocol WAMP Component, you need to drop this component in the form and select a TsgcWeb­
SocketClient Component using Client Property.
 

Methods
  Prefix: Procedures and Errors are identified using URIs or CURIEs, the client uses this method to send a new
prefix.
 
• aPrefix: compact URI expression.
• aURI: full URI.
 
  Subscribe: A client requests access to a valid topicURI (or CURIE from Prefix) to receive events published to the
given topicURI. The request is asynchronous, the server will not return an acknowledgement of the subscription.
 
• aTopicURI: channel name.
 
  UnSubscribe: Calling unsubscribe on a topicURI informs the server to stop delivering messages to the client pre­
viously subscribed to that topicURI.
 
• aTopicURI: channel name.
 
  Call: sent by the client when requests a Remote Procedure Call (RPC)
 
• aCallId: this is the UUID generated by client
• aProcURI: procedure identifier.
• aArguments: procedure params, can be a integer, a JSON object, a list...
 
  CancelCall: method called when the client wants cancel an active Call.
 
• aCallId: this is the UUID generated by client
 
  Publish: The client will send an event to all clients connected to the server who have subscribed to the topicURI.
 
• TopicURI: channel name.
• Event: message text.

Events
 OnWelcome: is the first server-to-client message sent by a WAMP server
 
• SessionId: is a string that is randomly generated by the server and unique to the specific WAMP ses­
sion. The sessionId can be used for at least two situations: 1) specifying lists of excluded or eligible
clients when publishing event and 2) in the context of performing authentication or authorization.
• ProtocolVersion: is an integer that gives the WAMP protocol version the server speaks, currently it
MUST be 1.
• ServerIdent: is a string the server may use to disclose it's version, software, platform or identity.
 
  OnCallError: event fired when the remote procedure call could not be executed, an error or exception occurred
during the execution or the execution of the remote procedure finishes unsuccessfully for any other reason, the
server responds by sending a message with error details
 
• CallId: this is the ID generated by the client when requesting a call to a procedure
• ErrorURI: identifies the error.
• ErrorDesc: error description.

247
COMPONENTS

• ErrorDetails: application error details, is optional.


 
  OnCallResult: event fired when the execution of the remote procedure finishes successfully, the server responds
by sending a message with the result.
 
• CallId: this is the ID generated by client when request a call to a procedure
• Result: is the result, can be a number, a JSON object...
 
  OnCallProgressResult: event fired when the execution of the remote procedure is in progress and there are still
more pending results.
 
• CallId: this is the ID generated by client when request a call to a procedure
• Result: is the result, can be a number, a JSON object...
 
  OnEvent: event fired when the client receives PubSub events published by subscribers via the EVENT message.
 
• TopicURI: channel name where is subscribed.
• Event: message text.
 
 
 

248
COMPONENTS

Protocol WAMP Javascript


 
Here you can find available methods, you need to replace {%host%} and {%port%} variables as needed, example:
if you have configured your sgcWebSocket server to listen port 80 on www.example.com website you need to con­
figure:
 

<script src="http://www.example.com:80/sgcWebSockets.js"></script>
<script src="http://www.example.com:80/wamp.esegece.com.js"></script>

 
 

Open Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
</script>

Send New Prefix

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
  socket.prefix('sgc', 'http://www.esegece.com');
</script>

 
 

Request RPC (Remote Procedure Call)

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
  socket.call('', 'sgc:CallTest', '20')
</script>

Subscribe to a TopicURI

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
  socket.subscribe('sgc:test)
</script>

 
 

249
COMPONENTS

UnSubscribe to a TopicURI

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
  socket.unsubscribe('sgc:test)
</script>

 
 

Publish message

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
  socket.publish('sgc:channel', 'Test Message', [], []);
</script>

Show Alert with Message Received

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.on('sgcmessage', function(event)
  {  
    alert(event.message);
  }
</script>

Show Alert OnCallResult or OnCallError

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
  socket.on('wampcallresult', function(event)
  {  
    alert('call result: ' + event.CallId + ' - ' + event.CallResult);
  }
  socket.on('wampcallprogressresult', function(event)
  {  
    alert('call progress result: ' + event.CallId + ' - ' + event.CallResult);
  }
  socket.on('wampcallerror', function(event)
  {  
    alert('call error: ' + event.CallId + ' - ' + event.ErrorURI + ' - ' + event.ErrorDesc +
' - ' + event.ErrorDetails);
  }
</script>

 
 
 

Show Alert OnEvent

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>

250
COMPONENTS

<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
  socket.on('wampevent', function(event)
  {  
    alert('call result: ' + event.TopicURI + ' - ' + event.Event);
  }
</script>

Show Alert OnConnect, OnDisconnect and OnError Events

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  var socket = new sgcws_wamp('ws://{%host%}:{%port%}');
  socket.on('open', function(event)
  {  
    alert('sgcWebSocket Open!');
  };
  socket.on('close', function(event)
  {  
    alert('sgcWebSocket Closed!');
  };
  socket.on('error', function(event)
  {  
    alert('sgcWebSocket Error: ' + event.message);
  };
</script>

Close Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  socket.close();
</script>

Get Connection Status

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/wamp.esegece.com.js"></script>
<script>
  socket.state();
</script>

251
COMPONENTS

WAMP | Subscribers
A subscriber receives events by first providing topics (aka channels) he is interested. Subsequently, the subscriber
will receive any events publishes to that topic.
To receive events from a topic, first has to subscribe to this topic.
 
WAMP Client
 

procedure OnMessageEvent(Connection: TsgcWSConnection; const Text: string);


begin
  ShowMessage(Text);
end;
 
oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClientWAMP := TsgcWSPClient_WAMP.Create(nil);
oClientWAMP.Client := oClient.
oClientWAMP.OnMessage := OnMessageEvent;
oClient.Active := True;
 
// Subscribe to topic after successful connect
oClient.Subscribe('myTopic');

 
WAMP Server
 

procedure OnSubscriptionEvent(Connection: TsgcWSConnection; const Subscription: string);


begin
  ShowMessage('Subscribed: ' + Subscription);
end;
 
oServer := TsgcWebSocketServer.Create(nil);
oServer.Port := 80;
oServerWAMP := TsgcWSPServer_WAMP.Create(nil);
oServerWAMP.OnSubscription := OnSubscriptionEvent;
oServerWAMP.Server := oServer;
oServerWAMP.Active := True;

252
COMPONENTS

WAMP | Publishers
A publisher sends (publishes) an event by providing a topic (aka channel) as the abstract address, not a specific
peer. Just call Publish method and pass as arguments the name of the topic and the message you want to send.
This message will be delivered to all subscribers of this topic. As a note, there is no need to subscribe to a topic to
publish messages on this topics.
 
There is no need to configure anything on server side, because messages are automatically broadcasted to clients
when a publish message is received.
 
WAMP Client
 

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClientWAMP := TsgcWSPClient_WAMP.Create(nil);
oClientWAMP.Client := oClient.
oClientWAMP.OnMessage := OnMessageEvent;
oClient.Active := True;
 
// Publish a message to all subscribers
oClient.Publish('myTopic', 'Hello subscribers myTopic');

253
COMPONENTS

WAMP | Simple RPC


The most common use of WAMP component is client requests a method server and server sends response to
client. Client can send only the name of the method and/or can pass some parameters required by server to calcu­
late the result. Server processes requests and if successful sends a response to client with the result. If there is any
error, server sends an error response to client.
As you see, there is only One request and One response (successful or not).
 
Example: server has a method called GetTime, so every time a client requests this method, server returns server
time.
 
WAMP Server
 

procedure OnServerCall(Connection: TsgcWSConnection; const CallId, ProcUri, Arguments: string);


begin
  if ProcUri = 'GetTime' then
    oServerWAMP.CallResult(CallId, FormatDateTime('yyyymmdd hh:nn:ss', Now))
  else
    oServer.WAMP.CallError(CallId, 'Unknown method');
end;
oServer := TsgcWebSocketServer.Create(nil);
oServer.Port := 80;
oServerWAMP := TsgcWSPServer_WAMP.Create(nil);
oServerWAMP.OnCall := OnServerCallEvent;
oServerWAMP.Server := oServer;
oServer.Active := True;

WAMP Client
 

procedure OnCallResultClient(Connection: TsgcWSConnection; CallId, Result: string);


begin
  ShowMessage(Result);
end;
procedure OnCallErrorClient(Connection: TsgcWSConnection; const Error: string);
begin
  ShowMessage(Error);
end;
oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClientWAMP := TsgcWSPClient_WAMP.Create(nil);
oClientWAMP.OnCallResult := OnCallResultClient;
oClientWAMP.OnCallError := OnCallErrorClient;
oClientWAMP.Client := oClient;
oClient.Active := True;
// After client has connected, request GetTime from server
oClientWAMP.Call('GetTime');

254
COMPONENTS

WAMP | RPC Progress Results


Sometimes, Remote Produce Calls require more than one result to finish requests, by default WAMP 1.0 protocol
doesn't allow Partial results in a call, this is a feature only for sgcWebSockets library.
The flow is very similar to a simple RPC, but here there are 1 or more partial results before CallResult is called to
finish the process.
Basically, a client requests a procedure to server and server can send a result or an error. If send a result, this can
be the final result or it must send most results later. If it's final result, will call method CallResult and the process
will be finished. If there are more results to send, will call method CallProgressResult.
 
Example: client requests server a method to receive every second the server time and stop after 20 messages.
 
WAMP Server
 

procedure OnServerCall(Connection: TsgcWSConnection; const CallId, ProcUri, Arguments: string);


var
  vNum: Integer;
begin
  if ProcUri = 'GetProgressiveTime' then
  begin
    vNum := StrToInt(Arguments);
    for i := 1 to vNum do
begin
          if i = 20 then
        oServerWAMP.CallResult(CallId, FormatDateTime('yyyymmdd hh:nn:ss', Now))
          else
            oServerWAMP.CallProgressiveResult(CallId, FormatDateTime('yyyymmdd hh:nn:ss', Now));
end
  end
  else
    oServer.WAMP.CallError(CallId, 'Unknown method');
end;

oServer := TsgcWebSocketServer.Create(nil);
oServer.Port := 80;
oServerWAMP := TsgcWSPServer_WAMP.Create(nil);
oServerWAMP.OnCall := OnServerCallEvent;
oServerWAMP.Server := oServer;
oServer.Active := True;

WAMP Client
 

procedure OnCallResultClient(Connection: TsgcWSConnection; CallId, Result: string);


begin
  ShowMessage(Result);
end;

procedure OnCallProgressResultClient(Connection: TsgcWSConnection; CallId, Result: string);


begin
  ShowMessage(Result);
end;

procedure OnCallErrorClient(Connection: TsgcWSConnection; const Error: string);


begin
  ShowMessage(Error);
end;

oClient := TsgcWebSocketClient.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClientWAMP := TsgcWSPClient_WAMP.Create(nil);
oClientWAMP.OnCallResult := OnCallResultClient;
oClientWAMP.OnCallProgressResult := OnCallProgressResultClient;
oClientWAMP.OnCallError := OnCallErrorClient;
oClientWAMP.Client := oClient;
oClient.Active := True;
// After client has connected, request GetTime from server
oClientWAMP.Call('GetProgressTime');

255
COMPONENTS

256
COMPONENTS

Protocol WAMP 2
WAMP provides Unified Application Routing in an open WebSocket protocol that works with different languages.
 
Using WAMP you can build distributed systems out of application components which are loosely coupled and com­
municate in (soft) real-time.
 
At its core, WAMP offers two communication patterns for application components to talk to each other:
 
• Publish & Subscribe (PubSub)
 
• Remote Procedure Calls (RPC)
 
WAMP is easy to use, simple to implement and based on modern Web standards: WebSocket, JSON and URIs.
 

Components
  TsgcWSPClient_WAMP2: Client Protocol WAMP2 VCL Component.
 

257
COMPONENTS

TsgcWSPClient_WAMP2
This is Client Protocol WAMP Component, you need to drop this component in the form and select a TsgcWeb­
SocketClient Component using Client Property.
 

Session Methods

• ABORT: Both the Router and the Client may abort the opening of a WAMP session by sending an
ABORT message.
 
Reason MUST be an URI.
Details MUST be a dictionary that allows to provide additional, optional closing information
(see below).
 
No response to an ABORT message is expected.
 
• GOODBYE: A WAMP session starts its lifetime with the Router sending a WELCOME message to the
Client and ends when the underlying transport disappears or when the WAMP session is closed ex­
plicitly by a GOODBYE message sent by one Peer and a GOODBYE message sent from the other
Peer in response.
 
Reason MUST be a URI.
Details MUST be a dictionary that allows providing additional, optional closing information.
 

Publish/Subscribe Methods

• PUBLISH: When a Publisher requests to publish an event to some topic, it sends a PUBLISH mes­
sage to a Broker:
 
Request is a random, ephemeral ID chosen by the Publisher and used to correlate the
Broker's response with the request.
Options is a dictionary that allows to provide additional publication request details in an exten­
sible way. This is described further below.
Topic is the topic published to.
Arguments is a list of application-level event payload elements. The list may be of zero length.
ArgumentsKw is an optional dictionary containing application-level event payload, provided as
keyword arguments. The dictionary may be empty.
 
If the Broker is able to fulfil and allowing the publication, the Broker will send the event to all current
Subscribers of the topic of the published event.
By default, publications are unacknowledged, and the Broker will not respond, whether the publication
was successful indeed or not.
 
• SUBSCRIBE: A Subscriber communicates its interest in a topic to a Broker by sending a SUB­
SCRIBE message:
 
Request MUST be a random, ephemeral ID chosen by the Subscriber and used to correlate
the Broker's response with the request.
Options MUST be a dictionary that allows providing additional subscription request details in
an extensible way.
Topic is the topic the Subscriber wants to subscribe to and MUST be a URI.
 
• UNSUBSCRIBE: When a Subscriber is no longer interested in receiving events for a subscription it
sends an UNSUBSCRIBE message
 
Request MUST be a random, ephemeral ID chosen by the Subscriber and used to correlate
the Broker's response with the request.
SUBSCRIBED.Subscription MUST be the ID for the subscription to unsubscribe from, origi­
nally handed out by the Broker to the Subscriber.
 

258
COMPONENTS

RPC Methods

• CALL: When a Caller wishes to call a remote procedure, it sends a CALL message to a Dealer:
 
Request is a random, ephemeral ID chosen by the Caller and used to correlate the Dealer's
response with the request.
Options is a dictionary that allows to provide additional call request details in an extensible
way. This is described further below.
Procedure is the URI of the procedure to be called.
Arguments is a list of positional call arguments (each of arbitrary type). The list may be of zero
length.
ArgumentsKw is a dictionary of keyword call arguments (each of arbitrary type). The dictio­
nary may be empty.
 
• REGISTERCALL: A Callee announces the availability of an endpoint implementing a procedure with
a Dealer by sending a REGISTER message:
 
Request is a random, ephemeral ID chosen by the Callee and used to correlate the Dealer's
response with the request.
Options is a dictionary that allows providing additional registration request details in a extensi­
ble way. This is described further below.
Procedure is the procedure the Callee wants to register
 
• UNREGISTERCALL: When a Callee is no longer willing to provide an implementation of the regis­
tered procedure, it sends an UNREGISTER message to the Dealer:
 
Request is a random, ephemeral ID chosen by the Callee and used to correlate the Dealer's
response with the request.
REGISTERED.Registration is the ID for the registration to revoke, originally handed out by
the Dealer to the Callee.
 
• INVOCATION: If the Dealer is able to fulfil (mediate) the call and it allows the call, it sends a INVOCA­
TION message to the respective Callee implementing the procedure:
 
Request is a random, ephemeral ID chosen by the Dealer and used to correlate the Callee's
response with the request.
REGISTERED.Registration is the registration ID under which the procedure was registered at
the Dealer.
Details is a dictionary that allows to provide additional invocation request details in an extensi­
ble way. This is described further below.
CALL.Arguments is the original list of positional call arguments as provided by the Caller.
CALL.ArgumentsKw is the original dictionary of keyword call arguments as provided by the
Caller.
 
• YIELD: If the Callee is able to successfully process and finish the execution of the call, it answers by
sending a YIELD message to the Dealer:
 
INVOCATION.Request is the ID from the original invocation request.
Options is a dictionary that allows providing additional options.
Arguments is a list of positional result elements (each of arbitrary type). The list may be of ze­
ro length.
ArgumentsKw is a dictionary of keyword result elements (each of arbitrary type). The dictio­
nary may be empty.
 
 

Events

 OnWAMPSession: After the underlying transport has been established, the opening of a WAMP session is initiat­
ed by the Client sending a HELLO message to the Router
 
• Realm: is a string identifying the realm this session should attach to
• Details: is a dictionary that allows to provide additional opening information
 
 

259
COMPONENTS

  OnWAMPWelcome: A Router completes the opening of a WAMP session by sending a WELCOME  reply mes­
sage to the Client.
 
• Session: MUST be a randomly generated ID specific to the WAMP session. This applies for the
lifetime of the session.
• Details: is a dictionary that allows to provide additional information regarding the open session.
 
 
  OnWAMPChallenge: this event is raised when server requires client authenticate against server.
 
• Authmethod: this is the authentication method requested by server, example: ticket.
• Details: optional
• Secret: here client can set secret key which will be used to authenticate.
 
Example: Authentication using ticket method.
 

// First OnWAMPSession event will be called asking details about new session, set realm and authentication id
// which will be sent to serve
 
procedure OnWAMPSession(Connection: TsgcWSConnection;
    var aRealm, aDetails: string);
begin
  aRealm := 'realm1';
  aDetails := '{"authmethods": ["ticket"], "authid": "joe"}';
end;
  
// If AuthId parameter is accepted by server, it will request an authentication through Challenge message,
// here you can set "secret key" of "authid" param.
 
procedure OnWAMPChallenge(Connection:
    TsgcWSConnection; AuthMethod, Details: string; var Secret: string);
begin
  Secret := 'your secret key';
end;
 
// If Authentication is successful, server will send a Welcome message
 
procedure OnWAMPWelcome(Connection: TsgcWSConnection;
    SessionId: Int64; Details: string);
begin
  ShowMessage('authenticated');
end;

 
 
  OnWAMPAbort: Both the Router and the Client may abort the opening of a WAMP session by sending an ABORT 
message.
 
• Reason: MUST be an URI.
• Details: MUST be a dictionary that allows providing additional, optional closing information.
 
 
 OnWAMPGoodBye: A WAMP session starts its lifetime with the Router sending a WELCOME message to the Client
and ends when the underlying transport disappears or when the WAMP session is closed explicitly by a GOODBYE
message sent by one Peer and a GOODBYE message sent from the other Peer in response.
 
• Reason: MUST be an URI.
• Details: MUST be a dictionary that allows to provide additional, optional closing information.
 
 

260
COMPONENTS

OnWAMPSubscribed: If the Broker is able to fulfill and allow the subscription, it answers by sending a SUB­
SCRIBED message to the Subscriber
 
• SUBSCRIBE.Request: MUST be the ID from the original request.
• Subscription: MUST be an ID chosen by the Broker for the subscription.
 
 
OnWAMPUnSubscribed: Upon successful unsubscription, the Broker sends an UNSUBSCRIBED message to the
Subscriber
 
• UNSUBSCRIBE.Request: MUST be the ID from the original request.
 
 
OnWAMPPublished: If the Broker is able to fulfill and allowing the publication, and
PUBLISH.Options.acknowledge == true, the Broker replies by sending a PUBLISHED message to the Publisher:
 
• PUBLISH.Request: is the ID from the original publication request.
• Publication: is a ID chosen by the Broker for the publication.
 
 
OnWAMPEvent: When a publication is successful and a Broker dispatches the event, it determines a list of re­
ceivers for the event based on Subscribers for the topic published to and, possibly, other information in the event.
Note that the Publisher of an event will never receive the published event even if the Publisher is also a Subscriber
of the topic published to. The Advanced Profile provides options for more detailed control over publication. When a
Subscriber is deemed to be a receiver, the Broker sends the Subscriber an EVENT message.
 
• SUBSCRIBED.Subscription: is the ID for the subscription under which the Subscriber receives the
event - the ID for the subscription originally handed out by the Broker to the Subscribe*.
• PUBLISHED.Publication: is the ID of the publication of the published event.
• DETAILS: is a dictionary that allows the Broker to provide additional event details in a extensible way.
• PUBLISH.Arguments: is the application-level event payload that was provided with the original publi­
cation request.
• PUBLISH.ArgumentKw: is the application-level event payload that was provided with the original
publication request.
 
 
OnWAMPError: When the request fails, the Broker sends an ERROR
 
• METHOD: is the ID of the Method.
• REQUEST.ID: is the ID of the Request.
• DETAILS: is a dictionary that allows the Broker to provide additional event details in a extensible way.
• ERROR: describes the message error.
• PUBLISH.Arguments: is the application-level event payload that was provided with the original publi­
cation request.
• PUBLISH.ArgumentKw: is the application-level event payload that was provided with the original
publication request.
 
 
OnWAMPResult: The Dealer will then send a RESULT message to the original Caller:
 
• CALL.Request: is the ID from the original call request.
• DETAILS: is a dictionary of additional details.
• YIELD.Arguments: is the original list of positional result elements as returned by the Callee.
• YIELD.ArgumentsKw: is the original dictionary of keyword result elements as returned by the Callee.
 
 
OnWAMPRegistered: If the Dealer is able to fulfill and allowing the registration, it answers by sending a REGIS­
TERED message to the Callee:
 
• REGISTER.Request: is the ID from the original request.
• Registration: is an ID chosen by the Dealer for the registration.
 
 
OnWAMPUnRegistered: When a Callee is no longer willing to provide an implementation of the registered proce­
dure, it sends an UNREGISTER message to the Dealer:

261
COMPONENTS

 
• Request: is a random, ephemeral ID chosen by the Callee and used to correlate the Dealer's re­
sponse with the request.
• REGISTERED.Registration: is the ID for the registration to revoke, originally handed out by the
Dealer to the Callee.
 
 
 

262
COMPONENTS

Protocol Default
This is default sub-protocol implemented using "JSONRPC 2.0" messages, every time you send a message using
this protocol, a JSON object is created with the following properties:
 
jsonrpc: A String specifying the version of the JSON-RPC protocol. MUST be exactly "2.0".
 
method: A String containing the name of the method to be invoked. Method names that begin with the word rpc fol­
lowed by a period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and
MUST NOT be used for anything else.
 
params: A Structured value that holds the parameter values to be used during the invocation of the method. This
member MAY be omitted.
 
id: An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not
included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD
NOT contain fractional parts [2]
 
 
JSON object example:
 

{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}

 
 

Features
• Publish/subscribe message pattern to provide one-to-many message distribution and decou­
pling of applications. Supports Wildcard characters, so you can subscribe to a hierarchy of
channels. Example: if you want to subscribe to all channels which start with 'news', then call
Subscribe('news*').
• A messaging transport that is agnostic to the content of the payload
• Acknowledgment of messages sent.
• Supports transactional messages through server local transactions. When the client com­
mits the transaction, the server processes all messages queued. If client rollback the transac­
tion, then all messages are deleted.
• Implements QoS (Quality of Service) for message delivery.

Components
  TsgcWSPClient_sgc: Server Protocol Default VCL Component.
 
  TsgcWSPClient_sgc: Client Protocol Default VCL Component.
 
  Javascript Component: Client Javascript Reference.
 

Browser Test
If you want to test this protocol with your favourite Web Browser, please type this URL (you need to define your
custom host and port)
 
  http://host:port/esegece.com.html
 
 

263
COMPONENTS

 
 
 
 

264
COMPONENTS

TsgcWSPServer_sgc
This is Server Protocol Default Component, you need to drop this component in the form and select a TsgcWeb­
SocketServer Component using Server Property.
 

Methods
   Subscribe / UnSubscribe: subscribe/unsubscribe to a channel.  Supports wildcard characters, so you can sub­
scribe to a hierarchy of channels. Example: if you want to subscribe to all channels which start with 'news', then call
Subscribe('news*'). 
 
   Publish: sends a message to all subscribed clients. Supports wildcard characters, so you can publish to a hierar­
chy of channels. Example: if you want to send a message to all subscribers to channels which start with 'news',
then call Publish('news*').
 
   RPCResult: if a call RPC from the client is successful, the server will respond with this method.
 
   RPCError: if a call RPC from the client it has an error, the server will respond with this method.
 
   Broadcast: sends a message to all connected clients, if you need to broadcast a message to selected channels,
use Channel argument.
 
   WriteData: sends a message to single or multiple selected clients.
 
 

Properties
   RPCAuthentication: if enabled, every time a client requests an RPC, method name needs to be authenticated
against a username and password.
 
    Methods: is a list of allowed methods. Every time a client sends an RPC first it will search if this method is de­
fined on this list, if it's not in this list, OnRPCAuthentication event will be fired.
 
    Subscriptions: returns a list of active subscriptions.
 
    UseMatchesMasks: if enabled, subscriptions and publish methods accepts wildcards, question marks... check
MatchesMask Delphi function to see all supported masks.
 
 

Events
   OnRPCAuthentication: if RPC Authentication is enabled, this event is fired to define if a client can call this
method or not.
 
   OnRPC: fired when the server receives an RPC from a client.
 
   OnNotification: fired every server receive a Notification from a client.
 
   OnBeforeSubscription: fired every time before a client subscribes to a custom channel. Allows denying a sub­
scription.
 
   OnSubscription: fired every time a client subscribes to a custom channel.
 
   OnUnSubscription: fired every time a client unsubscribes from a custom channel.
 
   OnRawMessage: this event is fired before a message is processed by component.

265
COMPONENTS

 
 
 
 
 
 

266
COMPONENTS

TsgcWSPClient_sgc
This is Client Protocol Default Component, you need to drop this component in the form and select a TsgcWeb­
SocketClient Component using Client Property.
 

Methods
  Publish: sends a message to all subscribed clients.
 
  RPC: Remote Procedure Call, client request a method and response will be handled OnRPCResult or OnRPCEr­
ror events.
 
  Notify: the client sends a notification to a server, this notification doesn't need a response.
 
  Broadcast: sends a message to all connected clients, if you need to broadcast a message to selected channels,
use Channel argument.
 
  WriteData: sends a message to a server. If you need to send a message to a custom
TsgcWSProtocol_Server_sgc, use "Guid" Argument. If you need to send a message to a single channel, use
"Channel" Argument.
 
  Subscribe: subscribe client to a custom channel. If the client is subscribed, OnSubscription event will be fired.
 
  Unsubscribe: unsubscribe client to a custom channel. If the client is unsubscribed, OnUnsubscription event will
be fired.
 
  UnsubscribeAll: unsubscribe client from all subscribed channel. If the client is unsubscribed, OnUnsubscription
event will be fired for every channel.
 
  GetSession: requests to server session id, data session is received OnSession Event.
 
  StartTransaction: begins a new transaction.
 
  Commit: server processes all messages queued in a transaction.
 
  RollBack: server deletes all messages queued in a transaction.
 
 
 
 

Events
  OnEvent: this event is fired every time a client receives a message from a custom channel.
 
  OnRPCResult: this event is fired when the client receives a successful response from the server after a RPC is
sent.
 
  OnRPCError: this event is fired when the client receives a error response from the server after an RPC is sent.
 
  OnAcknowledgment: this event is fired when the client receives error an acknowledgment from the server that
message has been received.
 
  OnRawMessage: this event is fired before a message is processed by the component.
 
  OnSession: this event is fired after a successful connection or after a GetSession request.
 
 
 

267
COMPONENTS

Properties
   Queue: disabled by default, if True all text/binary messages are not processed and queued until queue is dis­
abled.
 
   QoS: Three "Quality of Service" provided:
 
Level 0: "At most once", the message is delivered according to the best efforts of the underlying TCP/IP net­
work. A response is not expected and no retry semantics are defined in the protocol. The message arrives at
the server either once or not at all.
 
Level 1: "At least once", the receipt of a message by the server is acknowledged by an ACKNOWLEDG­
MENT message. If there is an identified failure of either the communications link or the sending device, or
the acknowledgement message is not received after a specified period of time, the sender resends the mes­
sage. The message arrives at the server at least once. A message with QoS level 1 has an ID param in the
message.
 
Level 2: "Exactly once", where message are assured to arrive exactly once. This level could be used, for ex­
ample, with billing systems where duplicate or lost messages could lead to incorrect charges being applied.
If there is an identified failure of either the communications link or the sending device, or the acknowledge­
ment message is not received after a specified period of time, the sender resends the message.
 
    Subscriptions: returns a list of active subscriptions.
 
 
 
 
 

268
COMPONENTS

TsgcIWWSPClient_sgc
This is Intraweb Client Protocol Default Component, you need to drop this component in the form and select a Tsg­
cIWWebSocketClient Component using Client Property.
 

Methods
  WriteData: sends a message to a server. If you need to send a message to a custom
TsgcWSProtocol_Server_sgc, use "Guid" Argument. If you need to send a message to a single channel, use
"Channel" Argument.
 
  Subscribe: subscribe client to a custom channel. If the client is subscribed, OnSubscription event will be fired.
 
  Unsubscribe: unsubscribe client to a custom channel. If client is unsubscribed, OnUnsubscription event will be
fired.

269
COMPONENTS

Protocol Default Javascript


Default Protocol Javascript sgcWebSockets uses sgcWebSocket.js and esegece.com.js files.
 
Here you can find available methods, you need to replace {%host%} and {%port%} variables as needed, example:
if you have configured your sgcWebSocket server to listen port 80 on www.example.com website you need to con­
figure:
 

<script src="http://www.example.com:80/sgcWebSockets.js"></script>
<script src="http://www.example.com:80/esegece.com.js"></script>

 
 

Open Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
</script>

Send Message

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.send('Hello sgcWebSockets!');
</script>

Show Alert with Message Received

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.on('sgcmessage', function(event)
  {  
    alert(event.message);
  }
</script>

Publish Message to test channel

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.publish('Hello sgcWebSockets!', 'test');
</script>

270
COMPONENTS

Show Alert with Event Message Received

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.on('sgcevent', function(event)
  {  
    alert('channel:' + event.channel + '. message: ' + event.message);
  }
</script>

Call RPC

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  var params = {param:10};
  socket.rpc(GUID(), 'test', JSON.stringify(params));
</script>

 
 

Handle RPC Response

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.on('sgcrpcresult', function(event)
  {  
    alert('result:' + event.result);
  }
  socket.on('sgcrpcerror', function(event)
  {  
    alert('error:' + event.code + ' ' + event.message);
  }
</script>

Call Notify

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  var params = {param:10};
  socket.notify('test', JSON.stringify(params));
</script>

Send Messages in a Transaction

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
 
  socket.starttransaction('sgc:test');
  socket.publish('Message1', 'sgc:test');
  socket.publish('Message2', 'sgc:test');

271
COMPONENTS

  socket.publish('Message3', 'sgc:test');
  socket.commit('sgc:test');
</script>

Show Alert OnSubscribe or OnUnSubscribe to a channel

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.on('sgcsubscribe', function(event)
  {  
    alert('subscribed: ' + event.channel);
  }
  socket.on('sgcunsubscribe', function(event)
  {  
    alert('unsubscribed: ' + event.channel);
  }
</script>

Show Alert OnConnect, OnDisconnect and OnError Events

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.on('open', function(event)
  {  
    alert('sgcWebSocket Open!');
  };
  socket.on('close', function(event)
  {  
    alert('sgcWebSocket Closed!');
  };
  socket.on('error', function(event)
  {  
    alert('sgcWebSocket Error: ' + event.message);
  };
</script>

Get Session

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.on('sgcsession', function(event)
  {  
    alert(event.guid);
  };
  socket.getsession();
</script>

Close Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  socket.close();
</script>

272
COMPONENTS

Get Connection Status

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
 
  socket.state();
</script>

 
 

Set QoS

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  
  socket.qoslevel1();
  socket.publish('message', 'channel');
</script>

 
 

Set Queue Level

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  
  socket.queuelevel2();
  socket.publish('message1', 'channel1');
  socket.publish('message2', 'channel1');
</script>

273
COMPONENTS

Protocol Dataset
This protocol inherits from Protocol Default and it's useful if you want to broadcast dataset changes over clients
connected to this protocol. It can be used in 2 modes:
 
1. Replicate database: the database changes are replicated to all client databases, example: a server has a data­
base with stock quotes and all connected clients receive quotes changes. There is a single database (in server)
and every client has his own database. Every time a quote is updated, this change is broadcasted to all connected
clients and every client update his own record database. Use UpdateMode: upWhereAll or upWhereChanged for
this mode type.
 
2. Database updates: here there is a single database shared by server and clients, and every time there is a client
that updates a record in a database, all other clients want to be notified about this update. Use UpdateMode: upRe­
freshAll for this mode.
 

Most common uses


• Update Mode
• How Replicate Table
• How Notify Updates
 
 
It uses "JSON-RPC 2.0" Object, and every time there is a dataset change, it sends all field values (* only fields sup­
ported) using Dataset Object.
 
To allow the component to search records on the dataset, you need to specify which fields are the Key, example: if
in your dataset, ID field is the key you will need to write a code like this
 

procedure OnAfterOpenDataSet(DataSet: TDataSet);


begin
  DataSet.FieldByName('ID').ProviderFlags :=
    Dataset.FieldByName('ID').ProviderFlags + [pfInKey];
end;

Components
  TsgcWSPServer_Dataset: Server Protocol Dataset VCL Component.
 
  TsgcWSPClient_Dataset: Client Protocol Dataset VCL Component.
 
  Javascript Component: Client Javascript Reference.
 

Browser Test
If you want to test this protocol with your favourite Web Browser, please type this URL (you need to define your
custom host and port)
 
  http://host:port/dataset.esegece.com.html
 
 

274
COMPONENTS

TsgcWSPServer_Dataset
This is Server Protocol Dataset Component, you need to drop this component in the form and select a TsgcWeb­
SocketServer Component using Server Property and select a Dataset Component using Dataset Property.
 
This component inherits from TsgcWSProtocol_Server_sgc all methods and properties.

Properties
    ApplyUpdates: if enabled, every time the server receives a dataset update from client, it will be saved on the
server side.
 
    NotifyUpdates: if enabled, every time dataset server changes, server broadcasts this change to all connected
clients.
 
    NotifyDeletes: if enabled, every time a record is deleted, server broadcasts this to all connected clients.
 
    AutoEscapeText: if enabled (disabled by default), automatically escape/unescape characters inside field values
like "{", "["...
 
    AutoSynchronize: if enabled, every time a client connects to the server, the server will send metadata and all
dataset records to client.
 
    FormatSettings: allows to set the format of double and datetime fields (to avoid conflicts between diffferent for­
mat settings of peers). This format must be the same for server and clients.
• DecimalSeparator: ","
• ThousandSeparator: "."
• DateSeparator: "/"
• TimeSeparator: ":"
• ShortDateFormat: "dd/mm/yyyy hh:nn:ss:zzz"
 
    UpdateMode:
• upWhereAll: (by default) all fields are broadcasted to clients,
• upWhereChanged: only Fields that have changed will be broadcasted to connected clients.
• upRefreshAll: dataset is refreshed to get the latest changes.
 
 

Methods
    BroadcastRecord: sends dataset record values to all connected clients.
 
    MetaData: sends metadata info to a client.
 
    Synchronize: sends all dataset records to a client.
 

Events
  These events are specific on the dataset protocol.
 
  OnAfterDeleteRecord: event fired after a record is deleted from Dataset.
 
  OnAfterNewRecord: event fired after a record is created on Dataset.
 
  OnAfterUpdateRecord: event fired after a record is updated on Dataset.
 
  OnBeforeDeleteRecord: event fired before a record is deleted from Dataset. If Argument "Handled" is True,
means that the user handles this event and if won't be deleted (by default this argument is False)

275
COMPONENTS

 
  OnBeforeNewRecord: event fired before a record is created on Dataset. If Argument "Handled" is True, means
that the user handles this event and if won't be inserted (by default this argument is False)
 
  OnBeforeUpdateRecord: event fired before a record is updated on Dataset.  If  Argument "Handled" is True,
means that the user handles this event and if won't be updated (by default this argument is False)
 
  OnBeforeDatasetUpdate: event fired before a dataset record is updated.
 
 
 
 
 

276
COMPONENTS

TsgcWSPClient_Dataset
This is Client Protocol Dataset Component, you need to drop this component in the form and select a TsgcWeb­
SocketClient Component using Client Property and select a Dataset Component using Dataset Property.
 
This component inherits from TsgcWSProtocol_Client_sgc all methods and properties.
 

Methods
  Subscribe_all: subscribe to all available channels
 
new: fired on new dataset record.
update: fired on post dataset record.
delete: fired on delete dataset record.
 
  Synchronize: requests all dataset records from the server
 
  GetMetaData: requests all dataset fields from server
 
 
 

Events
  These events are specific on the dataset protocol.
 
  OnAfterDeleteRecord: event fired after a record is deleted from Dataset.
 
  OnAfterNewRecord: event fired after a record is created on Dataset.
 
  OnAfterUpdateRecord: event fired after a record is updated on Dataset.
 
  OnAfterSynchronize: event fired after synchronization has ended.
 
  OnBeforeDeleteRecord: event fired before a record is deleted from Dataset. If Argument "Handled" is True,
means that the user handles this event and if won't be deleted (by default this argument is False)
 
  OnBeforeNewRecord: event fired before a record is created on Dataset. If Argument "Handled" is True, means
that user the handles this event and if won't be inserted (by default this argument is False)
 
  OnBeforeUpdateRecord: event fired before a record is updated on Dataset.  If  Argument "Handled" is True,
means that user the handles this event and if won't be updated (by default this argument is False)
 
  OnBeforeSynchronization: event fired before a synchronization starts.
 
  OnMetaData: event fired after a GetMetaData request. Example:
 

procedure OnMetaData(Connection: TsgcWSConnection; const JSON: TsgcObjectJSON);


var
  i: integer;
  vFieldName, vDataType: string;
  vDataSize: Integer;
  vKeyField: Boolean;
begin
  for i:= 0 to JSON.Count -1 do
  begin
    vFieldName := JSON.Item[i].Node['fieldname'].Value;
    vDataType := JSON.Item[i].Node['datatype'].Value;
    vDataSize := JSON.Item[i].Node['datasize'].Value;
    vKeyField := JSON.Item[i].Node['keyfield'].Value;

277
COMPONENTS

  end;
end;

Properties
   AutoSubscribe: enabled by default, if True, client subscribes to all available channels after successful connec­
tion.
 
   ApplyUpdates: if enabled, every time the client receives a dataset update from server, it will be saved on the
client side.
 
   AutoEscapeText: if enabled (disabled by default), automatically escape/unescape characters inside field values
like "{", "["...
 
   NotifyUpdates: if enabled, every time dataset client changes, it sends a message to server notifying this change.
 
   FormatSettings: allows to set the format of double and datetime fields (to avoid conflicts between diffferent for­
mat settings of peers). This format must be the same for server and clients.
• DecimalSeparator: ","
• ThousandSeparator: "."
• DateSeparator: "/"
• TimeSeparator: ":"
• ShortDateFormat: "dd/mm/yyyy hh:nn:ss:zzz"
 
   UpdateMode:
• upWhereAll: (by default) all fields are transmitted to the server,
• upWhereChanged: only Fields that have changed will be transmitted to the server.
• upRefreshAll: dataset is refreshed to get the latest changes.
 
 

278
COMPONENTS

TsgcIWWSPClient_Dataset
This is Intraweb Client Protocol Dataset Component, you need to drop this component in the form and select a Tsg­
cIWWebSocketClient Component using Client Property and select a Dataset Component using Dataset Property.
 
This component inherits from TsgcIWWSPClient_sgc all methods and properties.
 

Methods
  Subscribe_New: fired on new dataset record
  Subscribe_Update: fired on post dataset record
  Subscribe_Delete: fired on delete dataset record
 

279
COMPONENTS

Protocol Dataset Javascript


Dataset Protocol Javascript sgcWebSockets uses sgcWebSocket.js and dataset.esegece.com.js files.
 
Here you can find available methods, you need to replace {%host%} and {%port%} variables as needed, example:
if you have configured your sgcWebSocket server to listen port 80 on www.example.com website you need to con­
figure:
 

<script src="http://www.example.com:80/sgcWebSockets.js"></script>
<script src="http://www.example.com:80/dataset.esegece.com.js"></script>

 
 

Open Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  var socket = new sgcws_dataset('ws://{%host%}:{%port%}');
</script>

Send Message

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  var socket = new sgcws_dataset('ws://{%host%}:{%port%}');
  socket.send('Hello sgcWebSockets!');
</script>

Show Alert with Message Received

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  var socket = new sgcws('ws://{%host%}:{%port%}');
  socket.on('sgcdataset', function(event)
  {  
    alert(event.dataset);
  }
</script>

Show Alert with Dataset Received

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  var socket = new sgcws_dataset('ws://{%host%}:{%port%}');
  socket.on('sgcmessage', function(event)
  {  
    alert(event.message);

280
COMPONENTS

  }
</script>

Show Alert OnSubscribe or OnUnSubscribe to a channel

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  var socket = new sgcws_dataset('ws://{%host%}:{%port%}');
  socket.on('sgcsubscribe', function(event)
  {  
    alert('subscribed: ' + event.channel);
  }
  socket.on('sgcunsubscribe', function(event)
  {  
    alert('unsubscribed: ' + event.channel);
  }
</script>

Show Alert OnConnect, OnDisconnect and OnError Events

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  var socket = new sgcws_dataset('ws://{%host%}:{%port%}');
  socket.on('open', function(event)
  {  
    alert('sgcWebSocket Open!');
  };
  socket.on('close', function(event)
  {  
    alert('sgcWebSocket Closed!');
  };
  socket.on('error', function(event)
  {  
    alert('sgcWebSocket Error: ' + event.message);
  };
</script>

Subscribe All Dataset Changes

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  socket.subscribe_all();
</script>

UnSubscribe All Dataset Changes

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  socket.unsubscribe_all();
</script>

281
COMPONENTS

Handle Dataset Changes

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
var socket = new sgcws_dataset('ws://{%host%}:{%port%}');
 
socket.on('sgcdataset', function(evt){
 
if ((evt.channel == "sgc@dataset@new") || (evt.channel == "sgc@dataset@update")) {
 
... here you need to implement your own code insert/update records ...
}
else if (evt.channel == "sgc@dataset@delete") {
 
... here you need to implement your own code to delete records ...
 
}
});
</script>

 
 

Close Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  socket.close();
</script>

Get Connection Status

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/dataset.esegece.com.js"></script>
<script>
  socket.state();
</script>

282
COMPONENTS

Protocol Dataset | Replicate Table


This mode tries to solve a common scenario where a table is replicated for all connected clients, example, if you
have a server with a stock quotes table, you want broadcast stock changes to all clients, but you don't want
that a client can connect to your database. So, every time there is a change in any stock quotes, the record infor­
mation will be broadcasted to all connected clients. Every client will read the record and update his own table.
 
You can check in Demos folder, SQLLite/MultipleDatabase demo.

Configure Dataset Server


Create a new Dataset Protocol Server and configure using the following properties
 
• ApplyUpdates: set to True, every time there is a change, this will be broadcasted to clients
• AutoSynchronize: set to True, every time a new client connects to server, server will send all records
(metadata and data), so client will get latest information from server.
• UpdateMode: set to upWhereAll or upWhereChanged. The difference is the first send all fields of a record
and second only fields changed in a update.
 

oServer := TsgcWebSocketServer.Create(nil);
oProtocolDataset := TsgcWSPServer_Dataset.Create(nil);
oProtocolDataset.Server := oServer;
oProtocolDataset.Dataset := <...your dataset..>;
oProtocolDataset.ApplyUpdates := true;
oProtocolDataset.AutoSynchronize := true;
oProtocolDataset.NotifyUpdates := true;
oProtocolDataset.UpdateMode := upWhereAll;
oServer.Port := 80;
oServer.Active := true;

Configure Dataset Client


Create a new Dataset Protocol Client and configure using the following properties
 
• ApplyUpdates: set to True, every time there is a change, this will be sent to server.
• AutoSubscribe: set to True, every time a new client connects to server, client subscribe automatically to
update, delete and new record.
• UpdateMode: set to upWhereAll or upWhereChanged. The difference is the first send all fields of a record
and second only fields changed in a update.
 

oClient := TsgcWebSocketClient.Create(nil);
oProtocolDataset := TsgcWSPClient_Dataset.Create(nil);
oProtocolDataset.Client := oClient;
oProtocolDataset.Dataset := <...your dataset..>;
oProtocolDataset.ApplyUpdates := true;
oProtocolDataset.AutoSubscribe := true;
oProtocolDataset.NotifyUpdates := true;
oProtocolDataset.UpdateMode := upWhereAll;
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClient.Active := true;

283
COMPONENTS

Protocol Dataset | Notify Updates


This mode tries to solve an scenario where server and clients share a single database (server and clients are
connected to the same physical database) and clients want to be notified every time other client has done any
change on a dataset.
 
You can check in Demos folder, SQLLite/SingleDatabase demo.

Configure Dataset Server


Create a new Dataset Protocol Server and configure using the following properties
 
• ApplyUpdates: set to True, every time there is a change, this will be broadcasted to clients
• AutoSynchronize: set to False, here is not needed to set to true, because client is connected to the same
database than server.
• UpdateMode: set to upRefreshAll.
 

oServer := TsgcWebSocketServer.Create(nil);
oProtocolDataset := TsgcWSPServer_Dataset.Create(nil);
oProtocolDataset.Server := oServer;
oProtocolDataset.Dataset := <...your dataset..>;
oProtocolDataset.ApplyUpdates := true;
oProtocolDataset.AutoSynchronize := false;
oProtocolDataset.NotifyUpdates := true;
oProtocolDataset.UpdateMode := upRefreshAll;
>oServer.Port := 80;
oServer.Active := true;

Configure Dataset Client


Create a new Dataset Protocol Client and configure using the following properties
 
• ApplyUpdates: set to True, every time there is a change, this will be sent to server.
• AutoSubscribe: set to True, every time a new client connects to server, client subscribe automatically to
update, delete and new record.
• UpdateMode:  set to upRefreshAll.
 

oClient := TsgcWebSocketClient.Create(nil);
oProtocolDataset := TsgcWSPClient_Dataset.Create(nil);
oProtocolDataset.Client := oClient;
oProtocolDataset.Dataset := <...your dataset..>;
oProtocolDataset.ApplyUpdates := true;
oProtocolDataset.AutoSubscribe := true;
oProtocolDataset.NotifyUpdates := true;
oProtocolDataset.UpdateMode := upRefreshAll;
oClient.Host := '127.0.0.1';
oClient.Port := 80;
oClient.Active := true;

284
COMPONENTS

Protocol Files
This protocol allows sending files using binary WebSocket transport. It can handle big files with a low memory us­
age.
 

Features
• Publish/subscribe message pattern to provide one-to-many message distribution and decou­
pling of applications.
• Acknowledgment of messages sent.
• Implements QoS (Quality of Service) for file delivery.
• Optionally can request Authorization for files received.
• Low memory usage.

Components
  TsgcWSPServer_Files: Server Protocol Files VCL Component.
 
  TsgcWSPClient_Files: Client Protocol Files VCL Component.
 

Classes
  TsgcWSMessageFile: the object which encapsulates file packet information.
 

Most common uses


• Send Files
• How Send Files To Server
• How Send Files To Clients
• Big Files
• How Send Big Files
 

285
COMPONENTS

TsgcWSPServer_Files
This is the Server Files Protocol Component, you need to drop this component in the form and select a TsgcWeb­
SocketServer Component using Server Property.
 

Methods
   SendFile: sends a file to a client, you can set the following parameters
aSize: size of every packet in bytes.
aData: user custom data, here you can write any text you think is useful for client.
aChannel: if you only want to send data to all clients subscribed to this channel.
aQoS: type of quality of service.
aFileId: if empty, will be set automatically.
 
   BroadcastFile: sends a file to all connected clients. You can set several parameters:
aSize: size of every packet in bytes.
aData: user custom data, here you can write any text you think is useful for client.
aChannel: if you only want to send data to all clients subscribed to this channel.
aExclude: connection guids separated by a comma, which you don't want to send this file.
aInclude: connection guids separated by a comma, which you want to send this file.
aQoS: type of quality of service.
aFileId: if empty, will be set automatically.
 
 

Properties
   Files: files properties.
 
    BufferSize: default size of every packet sent, in bytes.
 
    SaveDirectory: the directory where all files will be stored.
 
    QoS: quality of service
 
    Interval: interval to check if a qosLevel2 message has been sent.
 
    Level: level of quality of service.
 
qosLevel0: the message is sent.
 
qosLevel1: the message is sent and you get an acknowledgment if the message has been
processed.
 
qosLevel2: the message is sent, you get an acknowledgment if the message has been processed
and packets are requested by the receiver.
 
    Timeout: maximum wait time.
 
    ClearReceivedStreamsOnDisconnect: if disabled, when reconnects, try to resume file download for qosLevel2,
by default is enabled.
 
    ClearSentStreamsOnDisconnect: tif disabled, when reconnects, try to resume file upload for qosLevel2, by de­
fault is enabled.
 
 
 

286
COMPONENTS

Events
   OnFileBeforeSent: fired before a file is sent. You can use this event to check file data before is sent.
 
   OnFileReceived: fired when a file is successfully received.
 
   OnFileReceivedAuthorization: fired to check if a file can be received.
 
   OnFileReceivedError: fired when an error occurs receiving a file.
 
   OnFileReceivedFragment: fired when a fragment file is received. Useful to show progress.
 
   OnFileSent: fired when a file is successfully sent.
 
   OnFileSentAcknowledgment: fired when a fragment is sent and the receiver has processed.
 
   OnFileSentError: fired when an error occurs sending a file.
 
   OnFileSentFragment: fired when a fragment file is sent. Useful to show progress.
 

287
COMPONENTS

TsgcWSPClient_Files
This is the Server Files Protocol Component, you need to drop this component in the form and select a TsgcWeb­
SocketClient Component using Client Property.
 

Methods
   SendFile: sends a file to the server, you can set the following parameters
aSize: size of every packet in bytes.
aData: user custom data, here you can write any text you think is useful for the server.
aQoS: type of quality of service.
aFileId: if empty, will be set automatically.
 

Properties
   Files: files properties
 
    BufferSize: default size of every packet sent, in bytes.
 
    SaveDirectory: the directory where all files will be stored.
 
    QoS: quality of service
 
    Interval: interval to check if a qosLevel2 message has been sent.
 
    Level: level of quality of service.
 
qosLevel0: the message is sent.
 
qosLevel1: the message is sent and you get an acknowledgment if the message has been
processed.
 
qosLevel2: the message is sent, you get an acknowledgment if the message has been processed
and packets are requested by the receiver.
 
    Timeout: maximum wait time.
 
    ClearReceivedStreamsOnDisconnect: if disabled, when reconnects, try to resume file download for qosLevel2,
by default is enabled.
 
    ClearSentStreamsOnDisconnect: tif disabled, when reconnects, try to resume file upload for qosLevel2, by de­
fault is enabled.
 

Events
   OnFileBeforeSent: fired before a file is sent. You can use this event to check file data before is sent.
 
   OnFileReceived: fired when a file is successfully received.
 
   OnFileReceivedAuthorization: fired to check if a file can be received.
 
   OnFileReceivedError: fired when an error occurs receiving a file.
 
   OnFileReceivedFragment: fired when a fragment file is received. Useful to show progress.
 
   OnFileSent: fired when a file is successfully sent.

288
COMPONENTS

 
   OnFileSentAcknowledgment: fired when a fragment is sent and the receiver has processed.
 
   OnFileSentError: fired when an error occurs sending a file.
 
   OnFileSentFragment: fired when a fragment file is sent. Useful to show progress.

289
COMPONENTS

TsgcWSMessageFile
This object is passed as a parameter every time a file protocol event is raised.
 

Properties
• BufferSize: default size of the packet.
• Channel: if specified, this file only will be sent to clients subscribed to specific channel.
• Method: internal method.
• FileId: identifier of a file, is unique for all files received/sent.
• Data: user custom data. Here the user can set whatever text.
• FileName: name of the file.
• FilePosition: file position in bytes.
• FileSize: Total file size in bytes.
• Id: identifier of a packet, is unique for every packet.
• QoS: quality of service of the message.
• Streaming: for internal use.
• Text: for internal use.

290
COMPONENTS

Protocol Files | How Send Files To Server


To send a File to Server, just call the method SendFile of Files Protocol and pass the full FileName as argument.
The file received by server, will be saved by default in the same directory where is the server executable or in the
Path set in the Files.SaveDirectory property.
 

// ... Create Server


oServer := TsgcWebSocketServer.Create(nil);
oServer_Files := TsgcWSPServer_Files.Create(nil);
oServer_Files.Server := oServer;
oServer.Host := '127.0.0.1';
oServer.Port := 8080;

// ... Create Client


oClient := TsgcWebSocketClient.Create(nil);
oClient.URL := 'ws://127.0.0.1:8080';

// ... Create Protocol


oClient_Files := TsgcWSPClient_Files.Create(nil);
oClient_Files.Client := oClient;

// ... Start Server


oServer.Active := True;

// ... Connect client and Send File


if oClient.Connect() then
  oClient_Files.SendFile('c:\Documents\yourfile.txt');

291
COMPONENTS

Protocol Files | How Send Files To Clients


To send a File to a Client, just call the method SendFile of Files Protocol and pass the Guid of the Connection and
the full FileName as argument. The Guid of the client connection can be captured OnConnect event of Server Pro­
tocol Files.
The file received by client, will be saved by default in the same directory where is the client executable or in the
Path set in the Files.SaveDirectory property.
 

// ... capture the guid of the client connection to send later the file
procedure OnConnectEvent(Connection: TsgcWSConnection);
begin
  FGuid := Connection.Guid;
end;

// ... Create Server


oServer := TsgcWebSocketServer.Create(nil);
oServer_Files := TsgcWSPServer_Files.Create(nil);
oServer_Files.Server := oServer;
oServer_Files.OnConnect := OnConnectEvent;
oServer.Host := '127.0.0.1';
oServer.Port := 8080;

// ... Create Client


oClient := TsgcWebSocketClient.Create(nil);
oClient.URL := 'ws://127.0.0.1:8080';

// ... Create Protocol


oClient_Files := TsgcWSPClient_Files.Create(nil);
oClient_Files.Client := oClient;

// ... Start Server and Connect Clients


oServer.Active := True;
oClient.Connect();

// ... Send File to the client connected


oServer_Files.SendFile(FConnection.Guid, 'c:\Documents\yourfile.txt');

292
COMPONENTS

Protocol Files | How Send Big Files


When you want to send big files to Server or Client, for example a File of some Gigabytes, you can experience
some memory problems trying to load the full file. The Protocol Files allows to send the files in smaller packets that
when received by other peer are reassembled in a single file. Just use the Size parameter of SendFile method to
set the Size in Bytes of every single packet.
 

// ... Create Server


oServer := TsgcWebSocketServer.Create(nil);
oServer_Files := TsgcWSPServer_Files.Create(nil);
oServer_Files.Server := oServer;
oServer.Host := '127.0.0.1';
oServer.Port := 8080;

// ... Create Client


oClient := TsgcWebSocketClient.Create(nil);
oClient.URL := 'ws://127.0.0.1:8080';

// ... Create Protocol


oClient_Files := TsgcWSPClient_Files.Create(nil);
oClient_Files.Client := oClient;

// ... Start Server


oServer.Active := True;

// ... Connect client and Send File in packets of 100000 bytes


if oClient.Connect() then
  oClient_Files.SendFile('c:\Documents\yourfile.txt', 100000, qosLevel0, '');

293
COMPONENTS

Protocol Presence
Presence protocol allows to know who is subscribed to a channel, this makes more easy to create chat applications
and know who is online, example: game users, chat rooms, users viewing the same document...

Features
• By default user is identified by a name, but this can be customized passing more data: email, company,
twitter...
• Events to Authorize if a Channel can be created, if a member is allowed...
• Every time a new member joins a channel, all members are notified.
• Publish messages to all channel subscribers.
• Low memory usage.

Components
  TsgcWSPServer_Presence: Server Protocol Presence VCL Component.
 
  TsgcWSPClient_Presence: Client Protocol Presence VCL Component.
 

Classes
  TsgcWSPresenceMessage: the object which encapsulates presence packet information.

294
COMPONENTS

TsgcWSPServer_Presence
This is Server Presence Protocol Component, you need to drop this component in the form and select a TsgcWeb­
SocketServer Component using Server Property.
 

Methods
All methods are handled internally by the server in response to client requests.

Properties
You must link this component to a Server or to a Broker if you are using more than one protocol.
 
EncodeBase64: by default is disabled, string values are encoded in base64 to avoid problems with JSON
encoding.
 
Acknowledgment: if enabled, every time a server sends a message to client assign an ID to this message
and queues in a list. When the client receives a message, if detect it has an ID, it sends an Acknowledgment
to the server, which means the client has processed message and server can delete from the queue.
 
• Interval: interval in seconds where server checks if there are messages not processed by
client.
• Timeout: maximum wait time before the server sends the message again.
 

Events
There are several events to handle actions like: a new member request to join a channel, a new channel is
created by a member, a member unsubscribes from a channel...

New Member
// When a new client connects to a server, first sends member data to the server to request a new member.
// Following events can be called:
 
// OnBeforeNewMember:
// Server receives a request from the client to join and the server accepts or not this member.
// Use Accept parameter to allow or not this member.
// By default all members are accepted.
 
procedure OnBeforeNewMember(aConnection:  TsgcWSConnection; const aMember: TsgcWSPresenceMember;
  var Accept: Boolean);
begin
  if aMember.Name = 'Spam' then
    Accept := False;
end;
 
// OnNewMember:
// After a new member is accepted, then this event is called and means this member has join member list. You can use aMe
// Data property to store objects in memory like database access, session objects...
 
procedure OnNewMember(aConnection: TsgcWSConnection; const aMember: TsgcWSPresenceMember);
begin
 

295
COMPONENTS

end;

Subscriptions
// When a client has joined as a member, can subscribe to new channels, if a channel not exists,
// the following events can be called:
 
// OnBeforeNewChannel:
// Server receives a subscription request from the client to join this channel but the channel doesn't exist,
// the server can accept or not to create this channel. Use Accept parameter to allow or not this channel.
// By default, all channels are accepted.
 
procedure OnBeforeNewChannelBeforeNewChannel(Connection: TsgcWSConnection; const aChannel: TsgcWSPresenceChannel;
  const aMember: TsgcWSPresenceMember; var Accept: Boolean)
begin
  if aChannel.Name = 'Spam' then
    Accept := False;
end;
 
// OnNewChannel: After a new channel is accepted, then this event is called and means a new channel has been created.
// Channel properties can be customized in this event.
 
procedure OnNewChannel(Connection: TsgcWSConnection; var aChannel: TsgcWSPresenceChannel);
begin
 
end;
 
// If the channel already exists or has been created, the server can accept or no new subscriptions.
 
// OnBeforeNewChannelMembers:
// Server receives a subscription request from a client to join this channel, the server can accept or not a member join
// Use Accept parameter to allow or not this member. By default, all members are accepted.
 
procedure OnBeforeNewChannelMember(Connection: TsgcWSConnection; const aChannel: TsgcWSPresenceChannel; const
  var Accept: Boolean)
begin
  if aMember.Name = 'John' then
    Accept := True
  else if aMember.Name = 'Spam' then
    Accept := False;
end;
 
// OnNewChannelMember:
// After a new member is accepted,  then this event is called and means a new member has joined the channel.
// All subscribers to this channel, will be notified about new members.
 
procedure OnNewChannelMember(Connection: TsgcWSConnection; const aChannel: TsgcWSPresenceChannel;
  const aMember: TsgcWSPresenceMember);
begin

UnSubscriptions
// Every time a member unjoin a channel or disconnects, the server is notified by following events:
 
// OnRemoveChannelMember:
// Server receives a subscription request from a client to join this channel but the channel doesn't exist,
// the server can accept or not to create this channel. Use Accept parameter to allow or not this channel.
// By default all channels are accepted.
 
procedure OnRemoveChannelMember(Connection: TsgcWSConnection; const aChannel: TsgcWSPresenceChannel;
  const aMember: TsgcWSPresenceMember);
begin
  Log('Member: ' + aMember.Name + ' unjoin channel: ' + aChannel.Name);
end;
 
// When a member disconnects, automatically server is notified:
 
// OnRemoveMember: when the client disconnects from protocol, this event is called and server is notified of
// which never has disconnected.
 
procedure OnRemoveMember(aConnection: TsgcWSConnection; aMember: TsgcWSPresenceMember);
begin
  Log('Member: ' + aMember.Name);  

end;

Errors
// Every time there is an error, these events are called, example: server has denied a member to subscribe

296
COMPONENTS

// to a channel, a member try to subscribe to an already subscribed channel...


 
//OnErrorMemberChannel: this event is called every time there is an error trying to create a new channel,
// join a new member, subscribe to a channel...
 
procedure OnErrorMemberChannel(Connection: TsgcWSConnection; const aError: TsgcWSPresenceError;
  const aChannel: TsgcWSPresenceChannel; const aMember: TsgcWSPresenceMember);
begin
  Log('#Error: ' + aError.Text);
end;
 
// When a member disconnects, automatically server is notified:
 
// OnErrorPublishMsg: when a client publish a message and this is denied by the server, this event is raised.
 
procedure OnErrorPublishMsg(Connection: TsgcWSConnection; const aError: TsgcWSPresenceError;
  const aMsg: TsgcWSPresenceMsg; const aChannel: TsgcWSPresenceChannel; const aMember: TsgcWSPresenceMember)
begin
  Log('#Error: ' + aError.Text);  
end;

297
COMPONENTS

TsgcWSPresenceMessage
This object encapsulates all internal messages exchange by server and client presence protocol.
 
 
TsgcWSPresenceMember
 
  ID: internal identifier
  Name: member name, provided by the client.
  Info: member additional info, provided by the client.
  Data: TObject which can be used for server purposes.
 
TsgcWSPresenceMemberList
 
  Member[i]: member of a list by index
  Count: number of members of the list
 
 
TsgcWSPresenceChannel
 
  Name: channel name, provided by the client.
 
 
TsgcWSPresenceMsg
 
  Text: text message, provided by the client when call Publish method
 
 
TsgcWSPresenceError
 
  Code: integer value identifying the error
  Text: error description.

298
COMPONENTS

TsgcWSPClient_Presence
This is Server Presence Protocol Component, you need to drop this component in the form and select a TsgcWeb­
SocketClient Component using Client Property.
 

Properties
 EncodeBase64: by default is disabled, string values are encoded in base64 to avoid problems with JSON encod­
ing.
 
 Presence: member data
 
•     Name: member name.
•     Info: any additional info related to member (example: email, twitter, company...)
 
Acknowledgment: if enabled, every time a client sends a message to server assign an ID to this message and
queues in a list. When the server receives the message, if detect it has an ID, it sends an Acknowledgment to the
client, which means the server has processed message and the client can delete from the queue.
 
• Interval: interval in seconds where the client checks if there are messages not processed by serv­
er.
• Timeout: maximum wait time before the client sends the message again.
 
 

Methods
There are several methods to subscribe to a channel, get a list of members...
 

Connect
// When a client connects, the first event called is OnSession, the server sends a session ID to the client,
// which identifies this client in the server connection list.
// After OnSession event is called, automatically client sends a request to the server to join as a member,
// if successful, OnNewMember event is raised
  
procedure OnNewMember(aConnection: TsgcWSConnection; const aMember: TsgcWSPresenceMember);
begin
 
end;

Subscriptions
// When a client wants subscribe to a channel, use method "Subscribe" and pass channel name as argument
 
Client.Subscribe('MyChannel');
  
// If the client is successfully subscribed, OnNewChannelMember event is called. All members of this channel
// will be notified using the same event.
  
procedure OnNewChannelMember(Connection: TsgcWSConnection; const aChannel: TsgcWSPresenceChannel;

299
COMPONENTS

  const aMember: TsgcWSPresenceMember);


begin
  Log('Subscribed: ' + aChannel.Name);
end;
 
// if server denies access to a member, OnErrorMemberChannel event is raised.
  
procedure OnErrorMemberChannel(Connection: TsgcWSConnection; const aError: TsgcWSPresenceError;
  const aChannel: TsgcWSPresenceChannel; const aMember: TsgcWSPresenceMember)
begin
  Log('Error: ' + aError.Text);
end;

  

UnSubscriptions
// When a client unsubscribe from a channel, use method "Unsubscribe" and pass channel name as argument
  
Client.Unsubscribe('MyChannel');
  
// If a client is successfully unsubscribed, OnRemoveChannelMember event is called. All members of this channel
// will be notified using the same event.
// All members of this channel will be notified using the same event.
  
procedure OnNewChannelMember(Connection: TsgcWSConnection; const aChannel: TsgcWSPresenceChannel;
  const aMember: TsgcWSPresenceMember);
begin
  Log('Unsubscribed: ' + aChannel.Name);
end;
  
// if a client can't unsubscribe from a channel, example: because is not subscribed,
// OnErrorMemberChannel event is raised.
  
procedure OnErrorMemberChannel(Connection: TsgcWSConnection; const aError: TsgcWSPresenceError;
  const aChannel: TsgcWSPresenceChannel; const aMember: TsgcWSPresenceMember)
begin
  Log('Error: ' + aError.Text);
end;
  
// When a client disconnects from the server, OnRemoveEvent is called.
  
procedure OnRemoveMember(aConnection: TsgcWSConnection; aMember: TsgcWSPresenceMember);
begin
  Log('#RemoveMember: ' + aMember.Name);
end;
  

  

Publish
// When a client wants to send a message to all members or all subscribers of a channel, use "Publish" method
  
Client.Publish('Hello All Members');
  
Client.Publish('Hello All Members of this channel', 'MyChannel');
  
// If a message is successfully published, OnPublishMsg event is called. All members of this channel will be
// notified using the same event.
  
procedure OnPublishMsg(Connection: TsgcWSConnection; const aMsg: TsgcWSPresenceMsg;
  const aChannel: TsgcWSPresenceChannel; const aMember: TsgcWSPresenceMember);
begin
  Log('#PublishMsg: ' + aMsg.Text + ' ' + aMember.Name);
end;
  
// if a message can't be published, OnErrorPublishMsg event is raised.
  
procedure OnErrorPublishMsg(Connection: TsgcWSConnection; const aError: TsgcWSPresenceError;
  const aMsg: TsgcWSPresenceMsg; const aChannel: TsgcWSPresenceChannel; const aMember: TsgcWSPresenceMember)
begin
  Log('#Error: ' + aError.Text);  
end;
 

  

GetMembers
// A client can request to the server a list of all members or all members subscribed to a channel. Use "GetMembers" met
  

300
COMPONENTS

Client.GetMembers;
 
Client.GetMembers('MyChannel');
  
// If a message is successfully processed by the server, OnGetMembers event is called
 
procedure OnGetMembers(Connection: TsgcWSConnection; const aMembers: TsgcWSPresenceMemberList;
  const aChannel: TsgcWSPresenceChannel);
var
  i: Integer;
begin
  for i := 0 to aMembers.Count - 1 do
    Log('#GetMembers: ' + aMembers.Member[i].ID + ' ' + aMembers.Member[i].Name);  
end;
  
// If there is an error because the member is not allowed or is not subscribed to channel,
// OnErrorMemberChannel event is raised
 
procedure OnErrorMemberChannel(Connection: TsgcWSConnection; const aError: TsgcWSPresenceError;
  const aChannel: TsgcWSPresenceChannel;
  const aMember: TsgcWSPresenceMember);
begin
  Log('Error: ' + aError.Text);
end;
  

Invite
// A client can invite to other member to subscribe to a channel.
 
Client.Invite('MyChannel', 'E54541D0F0E5R40F1E00FEEA');
 
// When the other member receives the invitation, OnChannelInvitation event is called and member
// can Accept or not the invitation.
 
procedure OnChannelInvitation(Connection: TsgcWSConnection; const aMember: TsgcWSPresenceMember;
  const aChannel: TsgcWSPresenceChannel; var Accept: Boolean);
begin
  if aChannel = 'MyChannel' then
    Accept := True
  else
    Accept := False;
end;

301
COMPONENTS

Protocol Presence Javascript


Presence Protocol Javascript sgcWebSockets uses sgcWebSocket.js and presence.esegece.com.js files.
 
Here you can find available methods, you must replace {%host%} and {%port%} variables as needed, example: if
you have configured your sgcWebSocket server to listen port 80 on www.example.com website you need to config­
ure:
 

<script src="http://www.example.com:80/sgcWebSockets.js"></script>
<script src="http://www.example.com:80/presence.esegece.com.js"></script>

 
 

Open Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
</script>

New Member after connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
  socket.on('sgcsession', function(event)
  {   
    socket.newmember(event.id, 'John', 'Additional Info');
  });
</script>

Subscribe to Topic 1 channel

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
  socket.subscribe('Topic 1');
</script>

Unsubscribe from Topic 1 channel

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
  socket.unsubscribe('Topic 1');
</script>

302
COMPONENTS

Publish Message to Topic 1 channel

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
  socket.publish('Hello sgcWebSockets!', 'Topic 1');
</script>

 
 

Receive Message

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
  socket.on('sgcpublishmsg', function(event)
  {  
    console.log('#publishmsg: ' + event.message.text);
  });
</script>

Get All Members Connected

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
  socket.on('sgcgetmembers', function(event)
  {  
    for (var i  in event.members) {
     console.log(event.members[i].id + ' ' + event.members[i].name);
    }
  });
  socket.getmembers();
</script>

Show Alert when Members subscribe/unsubscribe

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
  socket.on('sgcnewmember', function(event)
  {  
    alert('#new member: ' + event.member.name);
  }
  ); 
  socket.on('sgcremovemember', function(event)
  {  
    alert('#removed member: ' + event.member.name);
  }
  );
  socket.on('sgcnewchannelmember', function(event)
  {  
    alert('#new member: ' + event.member.name + ' in channel: ' + event.channel.name);
  }
  );
  socket.on('sgcremovechannelmember', function(event)
  {  
    alert('#remove member: ' + event.member.name + ' from channel: ' + event.channel.name);
  }
  );
</script>

303
COMPONENTS

Show Alert OnConnect, OnDisconnect and OnError Events

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  var socket = new sgcws_presence('ws://{%host%}:{%port%}');
  socket.on('open', function(event)
  {  
    alert('sgcWebSocket Open!');
  };
  socket.on('close', function(event)
  {  
    alert('sgcWebSocket Closed!');
  };
  socket.on('sgcerrormemberchannel', function(event)
  {  
    alert('#error member channel: ' + event.error.text);
  }
  ); 
  socket.on('sgcerrorpublishmsg', function(event)
  {  
    alert('#error publish: ' + event.error.text);
  }
  );
</script>

Close Connection

<script src="http://{%host%}:{%port%}/sgcWebSockets.js"></script>
<script src="http://{%host%}:{%port%}/presence.esegece.com.js"></script>
<script>
  socket.close();
</script>

 
 

304
COMPONENTS

WebSocket APIs
There are several implementations based on WebSockets: finance, message publishing, queues... sgcWebSockets
implements the most important APIs based on WebSocket protocol. In order to use an API, just attach API compo­
nent to the client and all messages will be handled by API component (only one API component can be attached to
a client).
 

Client APIs
 
API Description
Binance is an international multi-language cryptocurrency exchange.
Binance Futures allows to connect to Binance Futures WebSocket / REST Market Streams.
FTX FTX it's a Cryptocurrency Derivatives Exchange. Support for WebSocket API and R
Coinbase pro is an US-based crypto exchange. Trade Bitcoin (BTC), Ethereum (E
Coinbase Pro GBP. Support for WebSocket API and REST API.
SignalR is a library for ASP.NET developers that makes developing real-time web functionali
SignalRCore ASP.NET Core SignalR is an open-source library that simplifies adding real-time we
is a JavaScript library for real-time web applications. It enables real-time, bi-direction
SocketIO
clients and servers.
Kraken is a US-based cryptocurrency exchange.
Kraken Futures allows to connect Kraken Futures WebSocket / REST Market data.
Pusher Pusher is an easy and reliable platform with flexible pub/sub messaging, live user lis
FXCM also known as Forex Capital Markets, is a retail broker for trading on the foreign exc
Bitfinex is one of the world's largest and most advanced cryptocurrency trading platf
Bitfinex
Ethereum, Ripple, EOS, Bitcoin Cash, Iota, NEO, Litecoin, Ethereum Classic...
Bitstamp Bitstamp is one of the world's longest standing crypto exchange, supporting the bloc
Huobi is an international multi-language cryptocurrency exchange.
Cex is a cryptocurrency exchange and former Bitcoin cloud mining provider.
Bitmex is a cryptocurrency exchange and derivative trading platform.
Bittrex is a US-based cryptocurrency exchange.
3Commas it's a crypto trading bot.
Discord is one of the most popular communication tools for online gaming and streaming.
Blockchain Blockchain WebSocket API allows developers to receive Real-Time notifications abo
 
 
WebSocket APIs can be registered at runtime, just call Method RegisterAPI and pass API component as a para­
meter.
 
 

Other Client APIs


 
API Description
is a cloud-based instant messaging and voice over IP service. Users can send messa
Telegram
stickers, audio and files of any type.
RCON is a TCP/IP-based communication protocol which allows console commands to be iss
CryptoHopper it's a crypto trading bot and portfolio manager.
CryptoRobotics it's a crypto trading robot.
 

305
COMPONENTS

 
 

Server APIs

API Description
RTCMultiConnection is a WebRTC JavaScript library for peer-to-peer applic
RTCMultiConnection
conferencing, file sharing, media streaming etc.)
 
 

306
COMPONENTS

API Binance
Binance
 
Binance is an international multi-language cryptocurrency exchange. It offers some APIs to access Binance data.
The following APIs are supported:
 
1. WebSocket streams: allows to subscribe to some methods and get data in real-time. Events are pushed to
clients by server to subscribers. Uses WebSocket as protocol.
2. UserData stream: subscribed clients get account details. Requires an API key to authenticate and uses
WebSocket as protocol.
3. REST API: clients can request to server market and account data. Requires an API Key and Secret to au­
thenticate and uses HTTPs as protocol.
4. Futures: WebSocket Futures Market Data Streams are supported through the Binance Futures Client API.
 
The client supports Binance.us too, the following APIs are supported:
 
1. WebSocket streams: allows to subscribe to some methods and get data in real-time. Events are pushed to
clients by server to subscribers. Uses WebSocket as protocol.
2. UserData stream: subscribed clients get account details. Requires an API key to authenticate and uses
WebSocket as protocol.
3. REST API: clients can request to server market and account data. Requires an API Key and Secret to au­
thenticate and uses HTTPs as protocol.
 

Properties
Binance API has 2 types of methods: public and private. Public methods can be accessed without authentication,
example: get ticker prices. Only are only private and related to user data, those methods requires the use of Bi­
nance API keys.
 
• ApiKey: you can request a new api key in your binance account, just copy the value to this property.
• ApiSecret: API secret is only required for REST_API, websocket api only requires ApiKey for some meth­
ods.
• TestNet: if enabled it will connect to Binance Demo Account (by default false).
• HTTPLogOptions: stores in a text file a log of HTTP requests
• Enabled): if enabled, will store all HTTP requests of WebSocket API.
• FileName: full path of filename where logs will be stored
• REST: stores in a text file a log of REST API requests
• Enabled: if enabled, will store all HTTP Requests of REST API.
• FileName: full path of filename where logs will be stored.
• UserStream: if enabled the client will receive notifications on Account, Orders or Balance Updates (by de­
fault true).
• BinanceUS: if enabled, will connect to Binance.us Servers (instead of Binance.com servers which is the de­
fault).
• ListenKeyOnDisconnect: this property specifies what to do when the client disconnect from Binance
servers with an Active ListenKey.
◦ blkodDeleteListenKey: Delete the Active ListenKey doing an HTTP Request to Binance Servers
(this is the default).
◦ blkodClearListenKey: Doesn't deletes the ListenKey from Binance Servers and just clear the value
of the field.
◦ blkodDoNothing: does nothing, so the next time that connects to Binance will try to use the same
ListenKey.
• UseCombinedStreams: if enabled, will combine streams as
follows: {"stream":"<streamName>","data":<rawPayload>} (by default disabled)
 
 
 

307
COMPONENTS

Most common uses


• WebSockets API
• How Connect WebSocket API
• How Subscribe WebSocket Channel
• REST API
• How Get Market Data
• How Use Private REST API
• How Trade Spot
• Private Requests Time
 

WebSocket Stream API


Base endpoint is wss://stream.binance.com:9443, client can subscribe / unsubscribe from events after a successful
connection.
The following Subscription / Unsubscription methods are supported.
 
Parame­
Method Description
ters
AggregateTrades Symbol push trade information that is aggregated for a single taker order
Trades Symbol push raw trade information; each trade has a unique buyer and seller
Symbol, In­
KLine push updates to the current klines/candlestick every second, minute, hour...
terval
24hr rolling window mini-ticker statistics. These are NOT the statistics of the
MiniTicker Symbol
UTC day, but a 24hr rolling window for the previous 24hrs.
24hr rolling window mini-ticker statistics for all symbols that changed in an
array. These are NOT the statistics of the UTC day, but a 24hr rolling win­
AllMiniTickers  
dow for the previous 24hrs. Note that only tickers that have changed will be
present in the array.
24hr rolling window ticker statistics for a single symbol. These are NOT the
Ticker Symbol
statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.
24hr rolling window ticker statistics for all symbols that changed in an array.
These are NOT the statistics of the UTC day, but a 24hr rolling window for
AllMarketTickers  
the previous 24hrs. Note that only tickers that have changed will be present
in the array.
Pushes any update to the best bid or ask's price or quantity in real-time for a
BookTicker Symbol
specified symbol.
Pushes any update to the best bid or ask's price or quantity in real-time for
AllBookTickers  
all symbols.
Symbol, Top <levels> bids and asks, pushed every second. Valid <levels> are 5, 10,
PartialBookDepth
Depth or 20.
Order book price and quantity depth updates used to locally manage an or­
DiffDepth Symbol
der book.
 
After a successful subcription / unsubscription, client receives a message about it, where id is the result of Sub­
scribed / Unsubscribed method.
 

{
  "result": null,
  "id": 1
}

308
COMPONENTS

User Data Stream API


Requires a valid ApiKey obtained from your binance account, and ApiKey must be set in Binance.ApiKey property
of component.
 
The following data is pushed to client every time there is a change. There is no need to subscribe to any method,
this is done automatically if you set a valid ApiKey.
 
Method Description
Account Update Account state is updated with the outboundAccountInfo event.
Balance Update occurs during the following:
 
Balance Update
• Deposits or withdrawals from the account
• Transfer of funds between accounts (e.g. Spot to Margin)
Order Update Orders are updated with the executionReport event.
 
 

REST API
The base endpoint is: https://api.binance.com. All endpoints return either a JSON object or array. Data is returned
in ascending order. Oldest first, newest last.
 
Public API EndPoints
 
These endpoints can be accessed without any authorization.
 
General EndPoints
 
Method Parameters Description
Ping   Test connectivity to the Rest API.
Test connectivity to the Rest API and get the current server
GetServerTime  
time.
GetExchangeIn­
  Current exchange trading rules and symbol information
formation
 
 
Market Data EndPoints
 
Method Parameters Description
GetOrderBook Symbol Get Order Book.
GetTrades Symbol Get recent trades
GetHistorical­
Symbol Get older trades.
Trades
Get compressed, aggregate trades. Trades that fill at the time,
GetAggregate­
Symbol from the same order, with the same price will have the quantity
Trades
aggregated.
Kline/candlestick bars for a symbol. Klines are uniquely identi­
GetKLines Symbol, Interval
fied by their open time.
GetAver­
Symbol Current average price for a symbol.
agePrice
24 hour rolling window price change statistics. Careful when ac­
Get24hrTicker Symbol
cessing this with no symbol.
GetPriceTicker Symbol Latest price for a symbol or symbols.

309
COMPONENTS

GetBookTicker Symbol Best price/qty on the order book for a symbol or symbols.
 
 
 
Private API EndPoints
 
Requires an APIKey and APISecret to get authorized by server.
 
Account Data EndPoints
 
Method Parameters Description
NewOrder Symbol, Side, Type Send in a new order.
PlaceMarke­
Side, Symbol, Quantity Places a New Market Order
tOrder
Side, Symbol, Quantity, Limit­
PlaceLimitOrder Places a New Limit Order
Price
Side, Symbol, Quantity, Stop­
PlaceStopOrder Places a New Stop Order
Price, LimitPrice
Test new order creation and signature/recvWindow long. Cre­
TestNewOrder Symbol, Side, Type ates and validates a new order but does not send it into the
matching engine.
QueryOrder Symbol Check an order's status.
Cancel an active order. Cancel an active order. Either OrderId or
CancelOrder Symbol
OrigClientOrderId must be sent.
CancelAl­
Symbol (optional)  
lOpenOrders
Get all open orders on a symbol. Careful when accessing this
GetOpenOrders  
with no symbol.
GetAllOrders Symbol Get all account orders; active, canceled, or filled.
Symbol, Side, Quantity, Price,
NewOCO Send in a new OCO
StopPrice
CancelOCO Symbol Cancel an entire Order List
Retrieves a specific OCO based on provided optional parame­
QueryOCO Symbol
ters
GetAllOCO   Retrieves all OCO based on provided optional parameters
GetOpenOCO   Get All Open OCO.
GetAccountIn­
  Get current account information.
formation
GetAccount­
Symbol Get trades for a specific account and symbol.
TradeList
 

Events
Binance Messages are received in TsgcWebSocketClient component, you can use the following events:
 
OnConnect
After a successful connection to Binance server.
OnDisconnect
After a disconnection from Binance server
OnMessage
Messages sent by server to client are handled in this event.
OnError
If there is any error in protocol, this event will be called.
OnException

310
COMPONENTS

If there is an unhandled exception, this event will be called.


 
Additionally, there is a specific event in Binance API Component, called OnBinanceHTTPException, which is
raised every time there is an error calling an HTTP Request (REST API or WebSocket User Stream).

311
COMPONENTS

Binance | Connect WebSocket API


In order to connect to Binance WebSocket API, just create a new Binance API client and attach to TsgcWebSocket­
Client.
See below an example:

oClient := TsgcWebSocketClient.Create(nil);
oBinance := TsgcWSAPI_Binance.Create(nil);
oBinance.Client := oClient;
oClient.Active := True;

312
COMPONENTS

Binance | Subscribe WebSocket Channel


Binance offers a variety of channels where you can subscribe to get real-time updates of market data, orders...
Find below a sample of how subscribe to a Ticker:

oClient := TsgcWebSocketClient.Create(nil);
oBinance := TsgcWSAPI_Binance.Create(nil);
oBinance.Client := oClient;
oBinance.SubscribeTicker('bnbbtc');

procedure OnMessage(Connection: TsgcWSConnection; const aText: string);


begin
// here you will receive the ticker updates
end;

313
COMPONENTS

Binance | Get Market Data


Binance offers public Market Data through REST Endpoints, when you call one of these endpoints, you will get an
snapshot of the market data requested.
The Market Data Endpoints doesn't require authentication, so are freely available to all users.
 
Example: to get an snapshot of the ticker BNBBTC, do the following call

oBinance := TsgcWSAPI_Binance.Create(nil);
ShowMessage(oBinance.REST_API.GetPriceTicker('BNBBTC'));

314
COMPONENTS

Binance | Private REST API


The Binance REST API offer public and private endpoints. The Private endpoints requires that messages signed to
increase the security of transactions.
First you must login to your Binance account and create a new API, you will get the following values:
 
• ApiKey
• ApiSecret
 
These fields must be configured in the Binance property of the Binance API client component.
Once configured, you can start to do private requests to the Binance Pro REST API
 
*Private Requests, require that your local machine has the local time synchronized, if not, the requests will be re­
jected by Binance server. Check the following article about this, Binance Private Requests Time.
 

oBinance := TsgcWSAPI_Binance.Create(nil);
oBinance.Binance.ApiKey := '<your api key>';
oBinance.Binance.ApiSecret := '<your api secret>';
ShowMessage(oBinance.REST_API.GetAccountInformation);

315
COMPONENTS

Binance | Trade Spot


Binance allows to trade with spot using his REST API.
 

Configuration
First you must create an API Key in your binance account and add privileges to trading with Spot.
Once this is done, you can start spot trading.
First, set your ApiKey and your ApiSecret in the Binance Client Component, this will be used to sign the re­
quests sent to Binance server.
 

Place an Order
To place a new order, just call to method REST_API.NewOrder of Binance Client Component.
 
Depending of the type of the order (market, limit...) the API requires more or less fields.
 
Mandatory Fields
 
• Symbol: the product id symbol, example: BNBBTC
• Side: BUY or SELL
• type: the order type
• LIMIT
• MARKET
• STOP_LOSS
• STOP_LOSS_LIMIT
• TAKE_PROFIT
• TAKE_PROFIT_LIMIT
• LIMIT_MAKER
 
Additional Mandatory Fields based on Type
 
• LIMIT: timeInForce, quantity, price
• MARKET: quantity or quoteOrderQty
• STOP_LOSS / TAKE_PROFIT: quantity, stopPrice
• STOP_LOSS_LIMIT / TAKE_PROFIT_LIMIT: timeInForce, quantity, price, stopPrice
• LIMIT_MAKER: quantity, price
 
When you send an order, there are 2 possibilities:
 
1. Successful: the function NewOrder returns the message sent by binance server.
2. Error: the exception is returned in the event OnBinanceHTTPException.
 
 
Place Market Order 1 BNBBTC

oBinance := TsgcWSAPI_Binance.Create(nil);
oBinance.Binance.ApiKey := '<api key>';
oBinance.Binance.ApiSecret := '<api secret>';
ShowMessage(oBinance.REST_API.NewOrder('BNBBTC', 'BUY', 'MARKET', '', 1));

 
Place Limit Order 1 BNBBTC at 0.009260

oBinance := TsgcWSAPI_Binance.Create(nil);
oBinance.Binance.ApiKey := '<api key>';

316
COMPONENTS

oBinance.Binance.ApiSecret := '<api secret>';


ShowMessage(oBinance.REST_API.NewOrder('BNBBTC', 'BUY', 'LIMIT', 'GTC', 1, 0, 0.009260));

 
 

317
COMPONENTS

Binance | Private Requests Time


When you do a private request to Binance, the message is signed so increase the security of requests. The mes­
sage takes the local time and sends inside the signed message, if the local time has a difference greater than 5
seconds with Binance servers, the request will be rejected. So, it's important verify that your local time is synchro­
nized, you can do this using the synchronization time method for your OS.
 
You can check the Binance server time, calling method GetServerTime, which will return the time of the Binance
server

318
COMPONENTS

API Binance Futures


Binance
 
Binance is an international multi-language cryptocurrency exchange. It offers some APIs to access Binance data.
This component allows to get Binance Futures WebSocket Market Streams.
 
https://binance-docs.github.io/apidocs/futures/en
https://binance-docs.github.io/apidocs/delivery/en

Futures Contracts
Binance API has 2 types of methods: public and private. Public methods can be accessed without authentication,
example: get ticker prices. Only are only private and related to user data, those methods requires the use of Bi­
nance API keys.
 
• ApiKey: you can request a new api key in your binance account, just copy the value to this property.
• ApiSecret: API secret is only required for REST_API, websocket api only requires ApiKey for some meth­
ods.
• TestNet: if enabled it will connect to Binance Demo Account (by default false).
• HTTPLogOptions: stores in a text file a log of HTTP requests
• Enabled): if enabled, will store all HTTP requests of WebSocket API.
• FileName: full path of filename where logs will be stored
• REST: stores in a text file a log of REST API requests
• Enabled: if enabled, will store all HTTP Requests of REST API.
• FileName: full path of filename where logs will be stored.
• UserStream: if enabled the client will receive notifications on Account, Orders or Balance Updates (by de­
fault true).
• ListenKeyOnDisconnect: this property specifies what to do when the client disconnect from Binance
servers with an Active ListenKey.
◦ blkodDeleteListenKey: Delete the Active ListenKey doing an HTTP Request to Binance Servers
(this is the default).
◦ blkodClearListenKey: Doesn't deletes the ListenKey from Binance Servers and just clear the value
of the field.
◦ blkodDoNothing: does nothing, so the next time that connects to Binance will try to use the same
ListenKey.
• UseCombinedStreams: if enabled, will combine streams as
follows: {"stream":"<streamName>","data":<rawPayload>} (by default disabled)
 
Client can connect to USDT or COIN Binance Futures, set which contract you want to trade using FuturesCon­
tracts property:
 
• bfcUSDT: connects to USD-M Futures API.
• bfcCOIN: connects to COIN-M Futures API.
 
Client can connect to Production or Demo Binance accounts. If TestNet property is enabled, it will connect to Demo
account, otherwise will connect to production Binance Servers.
 
 

WebSocket Stream API


Client can subscribe / unsubscribe from events after a successful connection.
The following Subscription / Unsubscription methods are supported.
 
Parame­
Method Description
ters
The Aggregate Trade Streams push trade information that is aggregated for a
AggregateTrades Symbol
single taker order every 100 milliseconds.

319
COMPONENTS

Symbol, Up­ Mark price and funding rate for a single symbol pushed every 3 seconds or
MarkPrice
dateSpeed every second.
Update­ Mark price and funding rate for all symbols pushed every 3 seconds or every
AllMarkPrice
Speed second.
Symbol, In­ The Kline/Candlestick Stream push updates to the current klines/candlestick
KLine
terval every 250 milliseconds (if existing).
24hr rolling window mini-ticker statistics for a single symbol. These are NOT
MiniTicker Symbol the statistics of the UTC day, but a 24hr rolling window from requestTime to
24hrs before.
24hr rolling window mini-ticker statistics for all symbols. These are NOT the
statistics of the UTC day, but a 24hr rolling window from requestTime to
AllMiniTicker  
24hrs before. Note that only tickers that have changed will be present in the
array.
24hr rolling window ticker statistics for a single symbol. These are NOT the
Ticker Symbol statistics of the UTC day, but a 24hr rolling window from requestTime to
24hrs before.
24hr rolling window ticker statistics for all symbols. These are NOT the statis­
AllMarketTickers   tics of the UTC day, but a 24hr rolling window from requestTime to 24hrs be­
fore. Note that only tickers that have changed will be present in the array.
Pushes any update to the best bid or ask's price or quantity in real-time for a
BookTicker Symbol
specified symbol.
Pushes any update to the best bid or ask's price or quantity in real-time for all
AllBookTickers  
symbols.
The Liquidation Order Streams push force liquidation order information for
LiquidationOrders Symbol
specific symbol
The All Liquidation Order Streams push force liquidation order information for
AllLiquidationOrders  
all symbols in the market.
Symbol,
PartialBookDepth Top bids and asks, Valid are 5, 10, or 20.
Depth
Bids and asks, pushed every 250 milliseconds, 500 milliseconds, 100 mil­
DiffDepth Symbol
liseconds or in real time(if existing)
 
After a successful subcription / unsubscription, client receives a message about it, where id is the result of Sub­
scribed / Unsubscribed method.
 

{
  "result": null,
  "id": 1
}

User Data Stream API


Requires a valid ApiKey obtained from your binance account, and ApiKey must be set in Binance.ApiKey property
of component.
 
The following data is pushed to client every time there is a change. There is no need to subscribe to any method,
this is done automatically if you set a valid ApiKey.
 
Method Description
When the user's position risk ratio is too high, this stream will be pushed. This message
is only used as risk guidance information and is not recommended for investment strate­
Margin Call
gies. In the case of a highly volatile market, there may be the possibility that the user's
position has been liquidated at the same time when this stream is pushed out.

320
COMPONENTS

Balance Update occurs during the following:


 
Balance and Position Up­
• When balance or position get updated, this event will be pushed.
date • When "FUNDING FEE" changes to the user's balance.
•  
Order Update When new order created, order status changed will push such event.
 
 

REST API
All endpoints return either a JSON object or array. Data is returned in ascending order. Oldest first, newest last.
 
Public API EndPoints
 
These endpoints can be accessed without any authorization.
 
General EndPoints
 
Method Parameters Description
Ping   Test connectivity to the Rest API.
Test connectivity to the Rest API and get the current server
GetServerTime  
time.
GetExchangeIn­
  Current exchange trading rules and symbol information
formation
 
 
Market Data EndPoints
 
Method Parameters Description
GetOrderBook Symbol Get Order Book.
GetTrades Symbol Get recent trades
GetHistorical­
Symbol Get older trades.
Trades
Get compressed, aggregate trades. Trades that fill at the time,
GetAggregate­
Symbol from the same order, with the same price will have the quantity
Trades
aggregated.
Kline/candlestick bars for a symbol. Klines are uniquely identi­
GetKLines Symbol, Interval
fied by their open time.
24 hour rolling window price change statistics. Careful when ac­
Get24hrTicker Symbol
cessing this with no symbol.
GetPriceTicker Symbol Latest price for a symbol or symbols.
GetBookTicker Symbol Best price/qty on the order book for a symbol or symbols.
GetMarkPrice Symbol Mark Price and Funding Rate
GetFundin­
Symbol  
gRateHistory
GetOpenInterest Symbol Get present open interest of a specific symbol.
GetOpenInter­
Symbol, Period  
estStatistics
GetTopTrader­
Symbol, Period  
AccountRatio
GetTopTrader­
Symbol, Period  
PositionRatio
GetGlobalAc­
Symbol, Period  
countRatio

321
COMPONENTS

GetTakerVolume Symbol, Period  


 
 
Private API EndPoints
 
Requires an APIKey and APISecret to get authorized by server.
 
Account and Trades EndPoints
 
Method Parameters Description
ChangePosition­ Change user's position mode (Hedge Mode or One-way Mode )
DualPosition
Mode on EVERY symbol
GetCurrentPosi­ Get user's position mode (Hedge Mode or One-way Mode ) on
 
tionMode EVERY symbol
Symbol, Side, PositionSide,
NewOrder Send in a new order.
Type
PlaceMarke­
Side, Symbol, Quantity  
tOrder
Side, Symbol, Quantity, Limit­
PlaceLimitOrder  
Price
Side, Symbol, Quantity, Stop­
PlaceStopOrder  
Price, LimitPrice
PlaceTrail­ Side, Symbol, Quantity, aActi­
 
ingStopOrder vationPrice, aCallbackRate
QueryOrder Symbol Check an order's status.
Cancel an active order. Either OrderId or OrigClientOrderId
CancelOrder Symbol
must be sent.
CancelAl­
Symbol  
lOpenOrders
AutoCancelAl­ Cancel all open orders of the specified symbol at the end of the
Symbol, CountDownTimer
lOpenOrders specified countdown.
QueryCurren­
Symbol  
tOpenOrder
Get all open orders on a symbol. Careful when accessing this
GetOpenOrders Symbol
with no symbol.
GetAllOrders Symbol Get all account orders; active, canceled, or filled.
GetAccountBal­
   
ance
GetAccountIn­
  Get current account information.
formation
ChangeInitial­
Symbol, Leverage Change user's initial leverage of specific symbol market.
Leverage
ChangeMargin­
Symbol, MarginType  
Type
ModifyIsolated­
Symbol, Amount, Type  
PositionMargin
GetPositionMar­
ginChangeHis­ Symbol  
tory
GetPositionIn­
Symbol  
formation
GetAccount­
Symbol  
TradeList

322
COMPONENTS

GetIncomeHis­
Symbol  
tory
GetNotional­
LeverageBrack­ Symbol  
et
 
 
 

Events
Binance Futures Messages are received in TsgcWebSocketClient component, you can use the following events:
 
OnConnect
After a successful connection to Binance server.
OnDisconnect
After a disconnection from Binance server
OnMessage
Messages sent by server to client are handled in this event.
OnError
If there is any error in protocol, this event will be called.
OnException
If there is an unhandled exception, this event will be called.
 
Additionally, there is a specific event in Binance API Component, called OnBinanceHTTPException, which is
raised every time there is an error calling an HTTP Request (REST API or WebSocket User Stream).
 
 

323
COMPONENTS

API Binance Futures | Trade


Binance allows to trade with futures using his REST API.
 

Configuration
First you must create an API Key in your binance account and add privileges to trading with Futures.
Once this is done, you can start to trading with futures.
First you must select if you want to trade with USDT or COIN futures, there is a property called FuturesContracts
where you can set which future contract you want to trade
Then, set your ApiKey and your ApiSecret in the Binance Futures Client Component, this will be used to sign the
requests sent to Binance server.
 

Place an Order
To place a new order, just call to method REST_API.NewOrder of Binance Futures Client Component.
 
Depending of the type of the order (market, limit...) the API requires more or less fields.
 
Mandatory Fields
 
• Symbol: the product id symbol, example: BTCUSD_210326
• Side: BUY or SELL
• type: the order type
• LIMIT
• MARKET
• STOP
• TAKE_PROFIT
• STOP_MARKET
• TAKE_PROFIT_MARKET
• TRAILING_STOP_MARKET
 
Additional Mandatory Fields based on Type
 
• LIMIT: timeInForce, quantity, price
• MARKET: quantity
• STOP/TAKE_PROFIT: quantity, price, stopPrice
• STOP_MARKET/TAKE_PROFIT_MARKET: stopPrice
• TRAILING_STOP_MARKET: callbackRate
 
When you send an order, there are 2 possibilities:
 
1. Successful: the function NewOrder returns the message sent by binance server.
2. Error: the exception is returned in the event OnBinanceHTTPException.
 
 

324
COMPONENTS

API SocketIO
SocketIO
 
Socket.IO is a JavaScript library for real-time web applications. It enables real-time, bi-directional communication
between web clients and servers. It has two parts: a client-side library that runs in the browser, and a server-side li­
brary for Node.js. Both components have a nearly identical API. Like Node.js, it is event-driven.
 

Messages Types
 
  0: open (Sent from the server when a new transport is opened (recheck))
 
  1: close (Request the close of this transport but does not shut down the connection itself.)
 
  2: ping (Sent by the client. The server should answer with a pong packet containing the same data)
    example
      client sends: 2probe
      server sends: 3probe
 
  3: pong (Sent by the server to respond to ping packets.)
 
  4: string message (actual message, client and server should call their callbacks with the data.)
    example:
      42/chat,[“join”,”{room:1}"]
      4 is the message packet type in the engine.io protocol
      2 is the EVENT type in the socket.io protocol
      /chat is the data which is processed by socket.io
      socket.io will fire the “join” event
      will pass "room: 1" data. It is possible to omit namespace only when it is /.
 
  5: upgrade (Before engine.io switches a transport, it tests, if server and client can communicate over this trans­
port. If this test succeeds, the client sends an upgrade packets which requests the server to flush its cache on the
old transport and switch to the new transport.)
 
  6: noop (A noop packet. Used primarily to force a poll cycle when an incoming WebSocket connection is re­
ceived.)
 

Properties
    API: specifies SocketIO version:
 
ioAPI0: supports socket.io 0.* servers (selected by default)
 
ioAPI1: supports socket.io 1.* servers
 
ioAPI2: supports socket.io 2.* servers
 
ioAPI3: supports socket.io 3.* servers
 
ioAPI4: supports socket.io 4.* servers
 
    Base64: if enabled, binary messages are received as base64.
 
    HandShakeCustomURL: allows customizing URLl to get socket.io session.
 
    HandShakeTimestamp: only enable if you want to send timestamp as a parameter when a new session is re­
quested (enable this property if you try to access a gevent-socketio python server).

325
COMPONENTS

 
    Namespace: allows setting a namespace when connects to the server.
 
    Polling: disabling this property, client will connect directly to server using websocket as transport.
 
    Parameters: allows to set connection parameters.
 
    EncodeParameters: if enabled, parameters are encoded.
 

Methods
Use WriteData method to send messages to socket.io server (following Message Types sections)
1. call method add user and one parameter with John as user name

WriteData('42["add user", "John"]');

Events

OnHTTPRequest

Before a new websocket connection is established, socket.io server requires client open a new HTTP connection to
get a new session id. In some cases, socket.io server requires authentication using HTTP headers, you can use
this event to add custom HTTP headers, like Basic authorization or Bearer token authentication.

OnAfterConnect

This event is called after socket.io connection is successful and client can send messages to server. Here you can
subscribe to namespaces for example.

OnHTTPConnectionSSL

When a WebSocket server requires secure connections, you can get an error message like this when a client tries
to connect to server:
Error connecting with SSL. error:XXXXXXXX:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version
This error means that your client is trying to connect using a TLS version which is not supported by the server.
To resolve this error you must handle OnSSLAfterCreateHandler of WebSocket client component and set a newer
TLS version.
For example: here we are setting TLS 1.2 as a protocol version.

procedure TfrmWebSocketClient.SOCKETIOHTTPConnectionSSL(Sender: TObject;


    aSSLHandler: TIdSSLIOHandlerSocketBase);
begin
  TIdSSLIOHandlerSocketOpenSSL(aSSLHandler).SSLOptions.Method := sslvTLSv1_2;
end;

326
COMPONENTS

API Coinbase Pro


Coinbase Pro
 

APIs supported
• WebSockets API: connect to a public websocket server and provides real-time market data updates.
• REST API: The REST API has endpoints for account and order management as well as public market data.
 
 

Most common uses


• WebSockets API
• How Connect WebSocket API
• How Subscribe WebSocket Channel
• REST API
• How Get Market Data
• How Use Private REST API
• How Place Orders
• How Use SandBox Account
• Private Requests Time
 

WebSockets API
The websocket feed provides real-time market data updates for orders and trades. The websocket feed is publicly
available, but connections to it are rate-limited to 1 per 4 seconds per IP.
The websocket feed uses a bidirectional protocol, which encodes all messages as JSON objects. All messages
have a type attribute that can be used to handle the message appropriately.
 
You can subscribe to the following channels:
 
Method Arguments Description
To receive heartbeat messages for specific products once a second
SubscribeHeart­ aProductId: id of the subscribe to the heartbeat channel. Heartbeats also include sequence
Beat product numbers and last trade ids that can be used to verify no messages
were missed.
The status channel will send all products and currencies on a preset
SubscribeStatus  
interval.
The ticker channel provides real-time price updates every time a
aProductId: id of the
SubscribeTicker match happens. It batches updates in case of cascading matches,
product
greatly reducing bandwidth requirements.
The easiest way to keep a snapshot of the order book is to use the
aProductId: id of the
SubscribeLevel2 level2 channel. It guarantees delivery of all updates, which reduce a
product
lot of the overhead required when consuming the full channel.
If you are only interested in match messages you can subscribe to the
SubscribeMatch­ aProductId: id of the
matches channel. This is useful when you're consuming the remain­
es product
ing feed using the level 2 channel.
The full channel provides real-time updates on orders and trades.
aProductId: id of the These updates can be applied on to a level 3 order book snapshot to
SubscribeFull
product maintain an accurate and up-to-date copy of the exchange order
book.

327
COMPONENTS

This channel is a version of the full channel that only contains mes­
SubscribeUser   sages that include the authenticated user. Consequently, you need to
be authenticated to receive any messages.
 
Some of this channels requires Authenticate against Coinbase Pro servers. So first request your API keys in your
Coinbase Pro Account and then set the values in the property Coinbase of the component:
 
• ApiKey
• ApiSecret
• Passphrase
 
Authentication will result in a couple of benefits:
1. Messages where you're one of the parties are expanded and have more useful fields
2. You will receive private messages, such as lifecycle information about stop orders you placed
 
 
 

REST API

Private Endpoints

Private endpoints are available for order management, and account management.
Before being able to sign any requests, you must create an API key via the Coinbase Pro website. The API key will
be scoped to a specific profile. Upon creating a key you will have 3 pieces of information which you must remem­
ber:
 
• Key
• Secret
• Passphrase
 
The Key and Secret will be randomly generated and provided by Coinbase Pro; the Passphrase will be provided by
you to further secure your API access. Coinbase Pro stores the salted hash of your passphrase for verification, but
cannot recover the passphrase if you forget it.
 
You can restrict the functionality of API keys. Before creating the key, you must choose what permissions you
would like the key to have. The permissions are:
 
• View - Allows a key read permissions. This includes all GET endpoints.
• Transfer ­ Allows a key to transfer currency on behalf of an account, including deposits and withdraws. En­
able with caution - API key transfers WILL BYPASS two-factor authentication.
• Trade - Allows a key to enter orders, as well as retrieve trade data. This includes POST /orders and several
GET endpoints.
 
Accounts
 
Method Arguments Description
Get a list of trading accounts from the profile of the
ListAccounts  
API key.
Information for a single account. Use this endpoint
GetAccount aAccountId: id of the account when you know the account_id. API key must belong
to the same profile as the account.
List account activity of the API key's profile. Account
GetAccountHistory aAccountId: id of the account activity either increases or decreases your account
balance.
List holds of an account that belong to the same pro­
file as the API key. Holds are placed on an account
GetHolds aAccountId: id of the account for any active orders or pending withdraw requests.
As an order is filled, the hold amount is updated. If
an order is canceled, any remaining hold is re­

328
COMPONENTS

moved. For a withdraw, once it is completed, the


hold is removed.
 
Orders
 
Method Arguments Description
Get a list of trading accounts from the profile of the
ListAccounts  
API key.
Information for a single account. Use this endpoint
GetAccount aAccountId: id of the account when you know the account_id. API key must be­
long to the same profile as the account.
List account activity of the API key's profile. Account
GetAccountHistory aAccountId: id of the account activity either increases or decreases your account
balance.
List holds of an account that belong to the same
profile as the API key. Holds are placed on an ac­
count for any active orders or pending withdraw re­
GetHolds aAccountId: id of the account quests. As an order is filled, the hold amount is up­
dated. If an order is canceled, any remaining hold is
removed. For a withdraw, once it is completed, the
hold is removed.
aOrder: class that contains all pos­ Places a new order. Use only if you need to access
PlaceNewOrder
sible fields of an order to advanced order options.
aSide: buy or sell aProductId: id of
the product aAmount: amount of
PlaceMarketOrder order aUseFunds: by default false Places a new Market order.
aClient_oid: Order ID selected by
you to identify your order
aSide: buy or sell aProductId: id of
the product aSize: size of the order
aLimitPrice: price limit aTimeIn­
PlaceLimitOrder Force: GTC by default aPostOnly: Places a new Limit order.  
post only flag aClient_oid: Order
ID selected by you to identify your
order
aSide: buy or sell aProductId: id of
the product aSize: size of the order
aStopPrice: price of the stop
PlaceStopOrder aStop: loss or entry aTimeInForce: Places a new Stop Order
GTC by default aClient_oid: Order
ID selected by you to identify your
order
Cancel a previously placed order. Order must be­
CancelOrder aOrderId: id the of the order
long to the profile that the API key belongs to.
aClient_oid: Order ID selected by Cancel a previously placed order. Order must be­
CancelOrdersClient
you to identify your order long to the profile that the API key belongs to.
With best effort, cancel all open orders from the pro­
CancelAllOrders   file that the API key belongs to. The response is a
list of ids of the canceled orders.
 
Other
 
Method Arguments Description
GetFillsByOrderId aOrderId: id the of the order Get a list of recent fills of the API key's profile.

329
COMPONENTS

GetFillsByProduc­
aProductId: id of the product Get a list of recent fills of the API key's profile.
tId
This request will return information on your payment
GetCurrentEx­
  method transfer limits, as well as buy/sell limits per
changeLimits
currency.
aProfileId: id of the profile
Get a list of deposits from the profile of the API key,
ListDeposits aBefore: as DateTime aAfter: as
in descending order by created time.
DateTime aLimit: by default 100
GetDeposit aTransferId: id of the transfer Get information on a single deposit.
aAmount: The amount to deposit
DepositPayment­ aCurrency: the type of currency
Deposit funds from a payment method
Method aPaymentMethodId: ID of the pay­
ment method
aAmount: The amount to deposit Deposit funds from a coinbase account. You can
aCurrency: the type of currency move funds between your Coinbase accounts and
DepositCoinbase
aCoinbaseAccountId: ID of the your Coinbase Pro trading accounts within your dai­
coinbase account ly limits.
DepositGener­
  You can generate an address for crypto deposits.
ateAddress
aProfileId: id of the profile
Get a list of withdrawals from the profile of the API
ListWithdrawals aBefore: as DateTime aAfter: as
key, in descending order by created time.
DateTime aLimit: by default 100
GetWithdrawal aTransferId: id of the transfer Get information on a single withdrawal.
aAmount: The amount to withdraw­
WithdrawalPay­ al aCurrency: the type of currency
Withdraw funds to a payment method.
mentMethod aPaymentMethodId: ID of the pay­
ment method
aAmount: The amount to deposit Withdraw funds to a coinbase account. You can
WithdrawalCoin­ aCurrency: the type of currency move funds between your Coinbase accounts and
base aCoinbaseAccountId: ID of the your Coinbase Pro trading accounts within your dai­
coinbase account ly limits.
aAmount: The amount to deposit
aCurrency: the type of currency
WithdrawalCrypto Withdraws funds to a crypto address.
aCryptoAddress: a crypto address
of the recipient
aCurrency: the type of currency
GetWith­ Gets the network fee estimate when sending to the
aCryptoAddress: a crypto address
drawalFeeEstimate given address.
of the recipient
aFromCurrencyId: currency origin
aToCurrencyId: currency destina­
CreateConversion Convert between currencies.
tion aAmount: amount of from to
convert to
ListPaymentMeth­
  Get a list of your payment methods.
ods
CoinbaseListAc­
  Get a list of your coinbase accounts.
counts
This request will return your current maker & taker
GetFees  
fee rates, as well as your 30-day trailing volume.
aStartDate: from Date aEndDate:
Reports provide batches of historic information
to Date aProductId: id of the prod­
CreateReportFills about your profile in various human and machine
uct aFormat: pdf or csv aEmail:
readable forms.
optional e-mail

330
COMPONENTS

aStartDate: from Date aEndDate:


Reports provide batches of historic information
CreateReportAc­ to Date aAccountId: id of the ac­
about your profile in various human and machine
count count aFormat: pdf or csv aEmail:
readable forms.
optional e-mail
Once a report request has been accepted for pro­
GetReportStatus aReportId: id of the report cessing, the status is available by polling the report
resource endpoint.
ListProfiles aOnlyActive: by default False List your profiles.
GetProfile aProfileId: id of the profile Get a single profile by profile id.
aFromProfileId: The profile id the
API key belongs to and where the
funds are sourced aToProfileId:The
CreateProfileTrans­ Transfer funds from API key's profile to another user
target profile id of where funds will
fer owned profile.
be transferred to aCurrency: i.e.
BTC or USD aAmount: Amount of
currency to be transferred
GetMarginProfileIn­ Get information about your margin profile, such as
aProductId: id of the product.
formation your current equity percentage.
Get your buying power and selling power for a par­
ticular product.
GetMarginBuying­ For example: On BTC-USD, "buying power" refers
aProductId: id of the product.
Power to how much USD you can use to buy
BTC, and "selling power" refers to how much BTC
you can sell for USD.
GetMarginWith­ Returns the max amount of the given currency that
aCurrency: i.e. BTC or USD
drawalPower you can withdraw from your margin profile.
GetMarginAllWith­ Returns the max amount of each currency that you
 
drawalPowers can withdraw from your margin profile.
Returns a liquidation strategy that can be performed
GetMarginExitPlan   to get your equity percentage back to an acceptable
level (i.e. your initial equity percentage).
Returns a list of liquidations that were performed to
GetMarginListLiq­ aAfterDate: Request liquidation
get your equity percentage back to an acceptable
uidationHistory history after this date.
level.
GetMarginPosition­ Returns the amount in USD of loans that will be re­
 
RefreshAmounts newed in the next day and then the day after.
GetMarginStatus   Returns whether margin is currently enabled.
Get cryptographically signed prices ready to be
GetOracle   posted on­chain using Open Oracle smart con­
tracts.
 
 
 

331
COMPONENTS

Coinbase Pro | Connect WebSocket API


In order to connect to Coinbase Pro WebSocket API, just create a new Coinbase API client and attach to TsgcWeb­
SocketClient. See below an example:

oClient := TsgcWebSocketClient.Create(nil);
oCoinbase := TsgcWSAPI_Coinbase.Create(nil);
oCoinbase.Client := oClient;
oClient.Active := True;

332
COMPONENTS

Coinbase Pro | Subscribe WebSocket Chan­
nel
Coinbase Pro offers a variety of channels where you can subscribe to get real­time updates of market data, or­
ders... Find below a sample of how subscribe to a Ticker:

oClient := TsgcWebSocketClient.Create(nil);
oCoinbase := TsgcWSAPI_Coinbase.Create(nil);
oCoinbase.Client := oClient;
oCoinbase.SubscribeTicker('ETH-USD');

procedure OnCoinbaseMessage(Sender: TObject; aType, aRawMessage: string);


begin
// here you will receive the ticker updates
end;

333
COMPONENTS

Coinbase Pro | Get Market Data


Coinbase Pro offers public Market Data through REST Endpoints, when you call one of these endpoints, you will
get an snapshot of the market data requested.
The Market Data Endpoints doesn't require authentication, so are freely available to all users.
 
Example: to get an snapshot of the ticker BTC-USD, do the following call

oCoinbase := TsgcWSAPI_Coinbase.Create(nil);
ShowMessage(oCoinbase.REST_API.GetProductTicker('BTC-USD'));

334
COMPONENTS

Coinbase Pro | Private REST API


The Coinbase REST API offer public and private endpoints. The Private endpoints requires that messages signed
to increase the security of transactions.
First you must login to your Coinbase Pro account and create a new API, you will get the following values:
 
• ApiKey
• ApiSecret
• Passpfrase
 
These fields must be configured in the Coinbase property of the Coinbase Pro API client component.
Once configured, you can start to do private requests to the Coinbase Pro REST API
 

oCoinbase := TsgcWSAPI_Coinbase.Create(nil);
oCoinbase.Coinbase.ApiKey := '<your api key>';
oCoinbase.Coinbase.ApiSecret := '<your api secret>';
oCoinbase.Coinbase.ApiPassphrase := '<your passphrase>';
ShowMessage(oCoinbase.REST_API.GetAccountInformation);

335
COMPONENTS

Coinbase Pro | Private Requests Time


When you do a private request to Coinbase Pro, the message is signed so increase the security of requests. The
message takes the local time and sends inside the signed message, if the local time has a difference greater than
30 seconds with Coinbase Pro servers, the request will be rejected. So, it's important verify that your local time is
synchronized, you can do this using the synchronization time method for your OS.
 
You can check the Coinbase Pro server time, calling method GetTime, which will return the time of the Coinbase
Pro server
 
 

336
COMPONENTS

Coinbase Pro | Place Orders


In order to place new orders in Coinbase Pro, you require first your APIs to access your private data, check the fol­
lowing article How Use Private REST API.
 
Once you have configured your API keys, you can start to place orders

Market Order

Place a new Market Order, buy 0.002 contracts of BTC-USD

oCoinbase := TsgcWSAPI_Coinbase.Create(nil);
oCoinbase.Coinbase.ApiKey := 'your api key';
oCoinbase.Coinbase.ApiSecret := 'your api secret';
oCoinbase.Coinbase.ApiPassphrase := 'your passphrase';
ShowMessage(oCoinbase.REST_API.PlaceMarketOrder(coisBuy, 'BTC-USD', 0.002));

Limit Order

Place a new Limit Order, buy 0.002 contracts of BTC-USD at price limit of 10000

oCoinbase := TsgcWSAPI_Coinbase.Create(nil);
oCoinbase.Coinbase.ApiKey := 'your api key';
oCoinbase.Coinbase.ApiSecret := 'your api secret';
oCoinbase.Coinbase.ApiPassphrase := 'your passphrase';
ShowMessage(oCoinbase.REST_API.PlaceLimitOrder(coisBuy, 'BTC-USD', 0.002, 10000));

337
COMPONENTS

Coinbase Pro SandBox Account


Coinbase Pro allows to use a SandBox account where you can trade without real funds. This account requires to
create API keys different from production account.
To use the SandBox account, just set Coinbase.SandBox property to true, before do any request to API.
 

oCoinbase := TsgcWSAPI_Coinbase.Create(nil);
oCoinbase.Coinbase.ApiKey := 'your api key';
oCoinbase.Coinbase.ApiSecret := 'your api secret';
oCoinbase.Coinbase.ApiPassphrase := 'your passphrase';
oCoinbase.Coinbase.SandBox := True;
ShowMessage(oCoinbase.REST_API.ListAccounts);

338
COMPONENTS

API SignalRCore
SignalRCore
 
ASP.NET Core SignalR is an open-source library that simplifies adding real-time web functionality to apps. Real-
time web functionality enables server-side code to push content to clients instantly.
 
Good candidates for SignalR:
 
• Apps that require high-frequency updates from the server. Examples are gaming, social networks, voting,
auction, maps, and GPS apps.
• Dashboards and monitoring apps. Examples include company dashboards, instant sales updates, or travel
alerts.
• Collaborative apps. Whiteboard apps and team meeting software are examples of collaborative apps.
• Apps that require notifications. Social networks, email, chat, games, travel alerts, and many other apps use
notifications.
 
SignalRCore sgcWebSockets component uses WebSocket as transport to connect to a SignalRCore server, if this
transport is not supported, an error will be raised.
 

Hubs
SignalRCore uses hubs to communicate between clients and servers. SignalRCore provides 2 hub protocols: text
protocol based on JSON and binary protocol based on MessagePack. The sgcWebSockets component only imple­
ments JSON text protocol to communicate with SignalRCore servers.
To configure which Hub client will use, just set in SignalRCore/Hub property the name of the Hub before the client
connects to the server.
 

Connection
When a client opens a new connection to the server, sends a request message which contains format protocol and
version. sgcWebSockets always sends format protocol as JSON. The server will reply with an error if the protocol is
not supported by the server, this error can be handled using OnSignalRCoreError event, and if the connection is
successful, OnSignalRCoreConnect event will be called.
 
When a client connects to a SignalRCore server, it can send a ConnectionId which identifies client between ses­
sions, so if you get a disconnection client can reconnect to server passing same prior connection id. In order to get
a new connection id, just connect normally to the server and you can know ConnectionId using OnBeforeCon­
nectEvent. If you want to reconnect to the server and pass a prior connection id, use ReConnect method and
pass ConnectionId as a parameter.
 
 

SignalRCore Protocol
The SignalR Protocol is a protocol for two-way RPC over any Message-based transport. Either party in the connec­
tion may invoke procedures on the other party, and procedures can return zero or more results or an error. Exam­
ple: the client can request a method from the server and server can request a method to the client. There are the
following messages exchanged between server and clients:
 
• HandshakeRequest: the client sends to the server to agree on the message format.
• HandshakeResponse: server replies to the client an acknowledgement of the previous HandshakeRequest
message. Contains an error if the handshake failed.
• Close: called by client or server when a connection is closed. Contains an error if the connection was closed
because of an error.
• Invocation:  client or server sends a message to another peer to invoke a method with arguments or not.

339
COMPONENTS

• StreamInvocation: client or server sends a message to another peer to invoke a streaming method with ar­
guments or not. The Response will be split into different items.
• StreamItem: is a response from a previous StreamInvocation.
• Completion: means a previous invocation or StreamInvocation has been completed. Can contain a result if
the process has been successful or an error if there is some error.
• CancelInvocation: cancel a previous StreamInvocation request.
• Ping: is a message to check if the connection is still alive.
 
 

Authorization
Authentication can be enabled to associate a user with each connection and filter which users can access to re­
sources. Authentication is implemented using Bearer Tokens, client provide an access token and server validates
this token and uses it to identify then user.
In standard Web APIs, bearer tokens are sent in an HTTP Header, but when using websockets, token is transmit­
ted as a query string parameter.
The following methods are supported:
 
srcaRequestToken
 
If Authentication is enabled, the flow is:
 
1. First tries to get a valid token from server. Opens an HTTP connection against
Authentication.RequestToken.URL and do a POST using User and Password data.
2. If previous is successful, a token is returned. If not, an error is returned.
3. If token is returned, then opens a new HTTP connection to negotiate a new connection. Here, token is passed as
an HTTP Header.
4. If previous is successful, opens a websocket connection and pass token as query string parameter.
 
• Authentication.Enabled: if active, authorization will be used before a websocket connection is established.
• Authentication.Username: the username provided to server to authenticate.
• Authentication.Password: the secret word provided to server to authenticate.
• Authentication.RequestToken.PostFieldUsername: name of field to transmit username (depends of con­
figuration, check http javascript page to see which name is used).
• Authentication.RequestToken.PostFieldPassword: name of field to transmit password (depends of con­
figuration, check http javascript page to see which name is used).
• Authentication.RequestToken.URL: url where token is requested.
• Authentication.RequestToken.QueryFieldToken: name of query string parameter using in websocket con­
nection.
 
srcaSetToken
 
Here, you pass token directly to SignalRCore server (because token has been obtained from another server).
 
• Authentication.Enabled: if active, authorization will be used before a websocket connection is established.
• Authentication.SetToken.Token: token value obtained.
 

Communication between Client an Server


There are three kinds of interactions between server and clients:  
 

Invocations

The Caller sends a message to the Callee and expects a message indicating that the invocation has been complet­
ed and optionally a result of the invocation 
  
Example: client invokes SendMessage method and passes as parameters user name and text message. Sends an
Invocation Id to 
get a result message from the server.

340
COMPONENTS

SignalRCore.Invoke('SendMessage', ['John', 'Hello All.'], 'id-000001');


 
procedure OnSignalRCoreCompletion(Sender: TObject; Completion: TSignalRCore_Completion);
begin
  if Completion.Error  '' then
    ShowMessage('Something goes wrong.')
  else
    ShowMessage('Invocation Successful!');
end;

Non-Blocking Invocations

The Caller sends a message to the Callee and does not expect any further messages for this invocation. Invoca­
tions can be sent without an Invocation ID value. This indicates that the invocation is "non-blocking".
  
Example: client invokes SendMessage method and passes as parameters user name and text message. The
client doesn't expect any response from the server about the result of the invocation.
 

SignalRCore.Invoke('SendMessage', ['John', 'Hello All.']);

Streaming Invocations

The Caller sends a message to the Callee and expects one or more results returned by the Callee followed by a
message indicating the end of invocation.
  
Example: client invokes Counter method and requests 10 numbers with an interval of 500 milliseconds.

SignalRCore.InvokeStream('Counter', [10, 500], 'id-000002');


 
procedure OnSignalRCoreStreamItem(Sender: TObject; StreamItem: TSignalRCore_StreamItem; var Cancel: Boolean);
begin
  DoLog('#stream item: ' + StreamItem.Item);
end;
 
procedure OnSignalRCoreCompletion(Sender: TObject; Completion: TSignalRCore_Completion);
begin
  if Completion.Error  '' then
    ShowMessage('Something goes wrong.')
  else
    ShowMessage('Invocation Successful!');
end;

Invocations

In order to perform a single invocation, the Caller follows the following basic flow:

procedure Invoke(const aTarget: String; const aArguments: Array of Const; const aInvocationId: String = '');
procedure InvokeStream(const aTarget: String; const aArguments: Array of Const; const aInvocationId: String);

Allocate a unique Invocation ID value (arbitrary string, chosen by the Caller) to represent the invocation. Call Invoke
or InvokeStream method containing the Target being invoked, Arguments and InvocationId (if you don't send Invo­
cationId, you won't get completion result).
 
If the Invocation is marked as non-blocking (see "Non-Blocking Invocations" below), stop here and immediately
yield back to the application. Handle StreamItem or Completion message with a matching Invocation ID. 

SignalRCore.InvokeStream('Counter', [10, 500], 'id-000002');


 
procedure OnSignalRCoreStreamItem(Sender: TObject; StreamItem: TSignalRCore_StreamItem; var Cancel: Boolean);
begin
  if StreamItem.InvocationId = 'id-000002' then
    DoLog('#stream item: ' + StreamItem.Item);
end;
 
procedure OnSignalRCoreCompletion(Sender: TObject; Completion: TSignalRCore_Completion);

341
COMPONENTS

begin
  if StreamItem.InvocationId = 'id-000002' then
  begin
    if Completion.Error  '' then
      ShowMessage('Something goes wrong.')
    else
      ShowMessage('Invocation Successful!');
  end;
end;

You can call a single invocation and wait for completion.


 

function InvokeAndWait(const aTarget: String; aArguments: Array of Const; aInvocationId: String; out Completion: TSignalRCo
  const aTimeout: Integer = 10000): Boolean;
function InvokeStreamAndWait(const aTarget: String; const aArguments: Array of Const; const aInvocationId: String
  out Completion: TSignalRCore_Completion; const aTimeout: Integer = 10000): Boolean;

Allocate a unique Invocation ID value (arbitrary string, chosen by the Caller) to represent the invocation. Call In­
vokeAndWait or InvokeStreamAndWait method containing the Target being invoked, Arguments and InvocationId.
The program will wait till completion event is called or Time out has been exceeded. 

var
  oCompletion: TSignalRCore_Completion;
begin
  if SignalRCore.InvokeStreamAndWait('Counter', [10, 500], 'id-000002', oCompletion) then
    DoLog('#invoke stream ok: ' + oCompletion.Result)
  else
    DoLog('#invocke stream error: ' + oCompletion.Error);
  
 
procedure OnSignalRCoreStreamItem(Sender: TObject; StreamItem: TSignalRCore_StreamItem; var Cancel: Boolean);
begin
  if StreamItem.InvocationId = 'id-000002' then
    DoLog('#stream item: ' + StreamItem.Item);
end;

Cancel Invocation

If the client wants to stop receiving StreamItem messages before the Server sends a Completion message, the
client can send a CancelInvocation message with the same InvocationId used for the StreamInvocation message
that started the stream.

procedure OnSignalRCoreStreamItem(Sender: TObject; StreamItem: SignalRCore_StreamItem; var Cancel: Boolean);


begin
  if StreamItem.InvocationId = 'id-000002' then
    Cancel := True;
end;

Completion and Results

 
An Invocation is only considered completed when the Completion message is received. If the client receives an In­
vocation from the server, OnSignalRCoreInvocation event will be called.

procedure OnSignalRCoreInvocation(Sender: TObject; Invocation: TSignalRCore_Invocation);


begin
  if Invocation.Target = 'SendMessage' then
    ... your code here ...
end;
// Once invocation is completed, call Completion method to inform server invocation is finished.
// If result is successful, then call CompletionResult method:
SignalRCore.CompletionResult('id-000002', 'ok');
 
// If not, then call CompletionError method:
SignalRCore.CompletionError('id-000002', 'Error processing invocation.');

342
COMPONENTS

Close Connection

 
Sent by the client when a connection is closed. Contains an error reason if the connection was closed because of
an error.

SignalRCore.Close('Unexpected message').
  
// If the server close connection by any reason, OnSignalRCoreClose event will be called. 
procedure OnSignalRCoreClose(Sender: TObject; Close: TSignalRCore_Close);
begin
  DoLog('#closed: ' + Close.Error);
end;

Ping

The SignalR Hub protocol supports "Keep Alive" messages used to ensure that the underlying transport connection
remains active. These messages help ensure:
 
Proxies don't close the underlying connection during idle times (when few messages are being sent). If the underly­
ing connection is dropped without being terminated gracefully, the application is informed as quickly as possible.
 
Keep alive behaviour is achieved calling Ping method or enabling HeartBeat on WebSocket client. If the server
sends a ping to the client, the client will send automatically a response and OnSignalRCoreKeepAlive event will be
called.

procedure OnSignalRCoreKeepAlive(Sender: TObject);


begin
  DoLog('#keepalive');
end;

343
COMPONENTS

API SignalR
SignalR
 
SignalR component uses WebSocket as transport to connect to a SignalR server, if this transport is not supported,
an error will be raised.
SignalR client component has a property called SignalR where you can set following data:
 
• Hubs: contains a list of hubs the client is subscribing to.
• ProtocolVersion:  the version of the protocol used by the client, supports protocol versions from 1.2 to 1.5
• UserAgent: user agent used to connect to SignalR server.
 
 

Hubs Messages
 
Hubs API makes it possible to invoke server methods from the client and client methods from the server. The proto­
col used for persistent connection is not rich enough to allow expressing RPC (remote procedure call) semantics. It
does not mean however that the protocol used for hub connections is completely different from the protocol used
for persistent connections. Rather, the protocol used for hub connections is mostly an extension of the protocol for
persistent connections.
 
When a client invokes a server method it no longer sends a free-flow string as it was for persistent connections. In­
stead, it sends a JSON string containing all necessary information needed to invoke the method. Here is a sample
message a client would send to invoke a server method:
 

WriteData('{"H":"chathub","M":"Send","A":["Delphi Client","Test message"],"I":0}');

 
The payload has the following properties:
I – invocation identifier – allows to match up responses with requests
H – the name of the hub
M – the name of the method
A – arguments (an array, can be empty if the method does not have any parameters)
 
 
 
The component has the following events:
 

OnSignalRConnect
When the client connects successfully to the server, this event is raised.
 

344
COMPONENTS

OnSignalRDisconnect
When the client is disconnected from the server, this event is raised.
 

OnSignalRError
When there is an error in WebSocket connection.
 

OnSignalRMessage
The protocol used for persistent connection is quite simple. Messages sent to the server are just raw strings. There
isn’t any specific format they have to be in. Messages sent to the client are more structured. The properties you can
find in the message are as follows:
 
C – message id, present for all non-KeepAlive messages
M – an array containing actual data.
 

{"C":"d-9B7A6976-B,2|C,2","M":["Welcome!"]}

OnSignalRResult
When a server method is invoked the server returns a confirmation that the invocation has completed by sending
the invocation id to the client and – if the method returned a value – the return value, or – if invoking the method
failed – the error.
Here are sample results of a server method call:
 

{"I":"0"}

 
A server void method whose invocation identifier was "0" completed successfully.
 

{"I":"0", "R":42}

 
A server method returning a number whose invocation identifier was "0" completed successfully and returned the
value 42.
 

{"I":"0", "E":"Error occurred"}

OnSignalRKeepAlive
This event is raised when a KeepAlive message is received from the server.

345
COMPONENTS

API Kraken
Kraken
 

Overview
WebSockets API offers real-time market data updates. WebSockets is a bidirectional protocol offering fastest real-
time data, helping you build real-time applications. The public message types presented below do not require au­
thentication. Private-data messages messages can be subscribed on a separate authenticated endpoint.
 
Kraken offers a REST API too with Public market data and Private user data (which requires an authentication).
 

Configuration
 
Private API requires to get create an API from your Kraken account.
Kraken allows Test environment on WebSocket protocol, enable Beta property from Kraken Property to use this be­
ta feature.

APIs supported
 
• WebSockets Public API: connects to a public WebSocket server.
• WebSockets Private API: connects to a private WebSocket server and requires an API Key and API Secret
to Authenticate against server.
• REST Public API: connects to a public REST server.
• REST Private API: connects to a public REST server and requires an API Key and API Secret to Authenti­
cate against server.
 
 

Kraken Examples

How Connect to Public WebSocket Server

oClient := TsgcWebSocketClient.Create(nil);
oKraken := TsgcWSAPI_Kraken.Create(nil);
oKraken.Client := oClient;
oClient.Active := True;

How Connect to Private WebSocket Server

oClient := TsgcWebSocketClient.Create(nil);
oKraken := TsgcWSAPI_Kraken.Create(nil);
oKraken.Kraken.ApiKey := 'your api key';
oKraken.Kraken.ApiSecret := 'your api secret';
oKraken.Client := oClient;
oClient.Active := True;

How Get Ticker from REST API

oClient := TsgcWebSocketClient.Create(nil);
oKraken := TsgcWSAPI_Kraken.Create(nil);

346
COMPONENTS

oKraken.Client := oClient;
ShowMessage(oKraken.GetTicker(['XBTUSD']));

How Get Account Balance from REST API

oClient := TsgcWebSocketClient.Create(nil);
oKraken := TsgcWSAPI_Kraken.Create(nil);
oKraken.Kraken.ApiKey := 'your api key';
oKraken.Kraken.ApiSecret := 'your api secret';
oKraken.Client := oClient;
ShowMessage(oKraken.GetAccountBalance());

347
COMPONENTS

API Kraken | WebSockets Public API


Connection
URL: wss://ws.kraken.com
 
Once the socket is open you can subscribe to a public channel by sending a subscribe request message.
 

General Considerations
• All messages sent and received via WebSockets are encoded in JSON format
• All floating point fields (including timestamps) are quoted to preserve precision.
• Format of each tradeable pair is A/B, where A and B are ISO 4217-A3 for standardized assets and popular
unique symbol if not standardized.
• Timestamps should not be considered unique and not be considered as aliases for transaction ids. Also, the
granularity of timestamps is not representative of transaction rates.
 

Supported Pairs
ADA/CAD, ADA/ETH, ADA/EUR, ADA/USD, ADA/XBT, ATOM/CAD, ATOM/ETH, ATOM/EUR, ATOM/USD, ATOM/
XBT, BCH/EUR, BCH/USD, BCH/XBT, DASH/EUR, DASH/USD, DASH/XBT, EOS/ETH, EOS/EUR, EOS/USD,
EOS/XBT, GNO/ETH, GNO/EUR, GNO/USD, GNO/XBT, QTUM/CAD, QTUM/ETH, QTUM/EUR, QTUM/USD,
QTUM/XBT, USDT/USD, ETC/ETH, ETC/XBT, ETC/EUR, ETC/USD, ETH/XBT, ETH/CAD, ETH/EUR, ETH/GBP,
ETH/JPY, ETH/USD, LTC/XBT, LTC/EUR, LTC/USD, MLN/ETH, MLN/XBT, REP/ETH, REP/XBT, REP/EUR, REP/
USD, STR/EUR, STR/USD, XBT/CAD, XBT/EUR, XBT/GBP, XBT/JPY, XBT/USD, BTC/CAD, BTC/EUR, BTC/GBP,
BTC/JPY, BTC/USD, XDG/XBT, XLM/XBT, DOGE/XBT, STR/XBT, XLM/EUR, XLM/USD, XMR/XBT, XMR/EUR,
XMR/USD, XRP/XBT, XRP/CAD, XRP/EUR, XRP/JPY, XRP/USD, ZEC/XBT, ZEC/EUR, ZEC/JPY, ZEC/USD, XTZ/
CAD, XTZ/ETH, XTZ/EUR, XTZ/USD, XTZ/XBT
 

Methods

Ping

Client can ping server to determine whether connection is alive, server responds with pong.
This is an application level ping as opposed to default ping in WebSockets standard which is server initiated

Ticker

Ticker information includes best ask and best bid prices, 24hr volume, last trade price, volume weighted average
price, etc for a given currency pair. A ticker message is published every time a trade or a group of trade happens.
Subscribe to a ticker calling SubscribeTicker method:

SubscribeTicker(['XBT/USD']);

If subscription is successful, OnKrakenSubscribed event will be called:

procedure OnKrakenSubscribed(Sender: TObject;ChannelId: Integer; Pair, Subscription, ChannelName: string;


  ReqID:Integer);
begin
  DoLog('#subscribed: ' + Subscription + ' ' + Pair + ' ' + ChannelName);
end;

UnSubscribe calling UnSubscribeTicker method:

348
COMPONENTS

UnSubscribeTicker(['XBT/USD']);

If unsubscription is successful, OnKrakenUnSubscribed event will be called:

procedure OnKrakenUnSubscribed(Sender: TObject; ChannelId: Integer; Pair, Subscription: string;


  ReqID: Integer);
begin
  DoLog('#unsubscribed: ' + Subscription + ' ' + Pair);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenSubscriptionError event will be called.

procedure OnKrakenSubscriptionError(Sender: TObject; ErrorMessage, Pair, Subscription: string;


  ReqID: Integer);
begin
  DoLog('#subscription error: ' + ErrorMessage);
end;

Ticker updates will be notified in OnKrakenData event.

 
[
  0,
  {
    "a": [
      "5525.40000",
      1,
      "1.000"
    ],
    "b": [
      "5525.10000",
      1,
      "1.000"
    ],
    "c": [
      "5525.10000",
      "0.00398963"
    ],
    "v": [
      "2634.11501494",
      "3591.17907851"
    ],
    "p": [
      "5631.44067",
      "5653.78939"
    ],
    "t": [
      11493,
      16267
    ],
    "l": [
      "5505.00000",
      "5505.00000"
    ],
    "h": [
      "5783.00000",
      "5783.00000"
    ],
    "o": [
      "5760.70000",
      "5763.40000"
    ]
  },
  "ticker",
  "XBT/USD"
]

OHLC

When subscribed for OHLC, a snapshot of the last valid candle (irrespective of the endtime) will be sent, followed
by updates to the running candle. For example, if a subscription is made to 1 min candle and there have been no
trades for 5 mins, a snapshot of the last 1 min candle from 5 mins ago will be published. The endtime can be used
to determine that it is an old candle.
Subscribe to a OHLC calling SubscribeOHLC method, you must pass pair and interval.

349
COMPONENTS

SubscribeOHLC(['XBT/USD'], kin1min);

If subscription is successful, OnKrakenSubscribed event will be called:

procedure OnKrakenSubscribed(Sender: TObject;ChannelId: Integer; Pair, Subscription, ChannelName: string;


  ReqID:Integer);
begin
  DoLog('#subscribed: ' + Subscription + ' ' + Pair + ' ' + ChannelName);
end;

UnSubscribe calling UnSubscribeOHLC method:

 
UnSubscribeOHLC(['XBT/USD'], kin1min);

If unsubscription is successful, OnKrakenUnSubscribed event will be called:

 
procedure OnKrakenUnSubscribed(Sender: TObject; ChannelId: Integer; Pair, Subscription: string;
  ReqID: Integer);
begin
  DoLog('#unsubscribed: ' + Subscription + ' ' + Pair);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenSubscriptionError event will be called.

 
procedure OnKrakenSubscriptionError(Sender: TObject; ErrorMessage, Pair, Subscription: string;
  ReqID: Integer);
begin
  DoLog('#subscription error: ' + ErrorMessage);
end;

OHLC updates will be notified in OnKrakenData event.

[
  42,
  [
    "1542057314.748456",
    "1542057360.435743",
    "3586.70000",
    "3586.70000",
    "3586.60000",
    "3586.60000",
    "3586.68894",
    "0.03373000",
    2
  ],
  "ohlc-5",
  "XBT/USD"
]

Trade

Trade feed for a currency pair.


Subscribe to Trade feed calling SubscribeTrade method.

 
SubscribeTrade(['XBT/USD']);

If subscription is successful, OnKrakenSubscribed event will be called:

 
procedure OnKrakenSubscribed(Sender: TObject;ChannelId: Integer; Pair, Subscription, ChannelName:
  string; ReqID:Integer);
begin
  DoLog('#subscribed: ' + Subscription + ' ' + Pair + ' ' + ChannelName);
end;

UnSubscribe calling UnSubscribeTrade method:

350
COMPONENTS

 
UnSubscribeTrade(['XBT/USD']);

If unsubscription is successful, OnKrakenUnSubscribed event will be called:

  
procedure OnrakenUnSubscribed(Sender: TObject; ChannelId: Integer; Pair, Subscription: string;
  ReqID: Integer);
begin
  DoLog('#unsubscribed: ' + Subscription + ' ' + Pair);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenSubscriptionError event will be called.

   
procedure OnKrakenSubscriptionError(Sender: TObject; ErrorMessage, Pair, Subscription: string;
  ReqID: Integer);
begin
  DoLog('#subscription error: ' + ErrorMessage);
end;

Trade updates will be notified in OnKrakenData event.

[
  0,
  [
    [
      "5541.20000",
      "0.15850568",
      "1534614057.321597",
      "s",
      "l",
      ""
    ],
    [
      "6060.00000",
      "0.02455000",
      "1534614057.324998",
      "b",
      "l",
      ""
    ]
  ],
  "trade",
  "XBT/USD"
]

Book

Order book levels. On subscription, a snapshot will be published at the specified depth, following the snapshot, lev­
el updates will be published.
Subscribe to a Book calling SubscribeBook method, you must pass pair and depth.

  
SubscribeBook(['XBT/USD'], kde10);

If subscription is successful, OnKrakenSubscribed event will be called:

   
procedure OnKrakenSubscribed(Sender: TObject;ChannelId: Integer; Pair, Subscription, ChannelName: string;
  ReqID:Integer);
begin
  DoLog('#subscribed: ' + Subscription + ' ' + Pair + ' ' + ChannelName);
end;

UnSubscribe calling UnSubscribeBook method:

    
UnSubscribeBook(['XBT/USD'], kde10);

If unsubscription is successful, OnKrakenUnSubscribed event will be called:

351
COMPONENTS

  
procedure OnKrakenUnSubscribed(Sender: TObject; ChannelId: Integer; Pair, Subscription: string;
  ReqID: Integer);
begin
  DoLog('#unsubscribed: ' + Subscription + ' ' + Pair);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenSubscriptionError event will be called.

   
procedure OnKrakenSubscriptionError(Sender: TObject; ErrorMessage, Pair, Subscription: string; ReqID: Integer);
begin
  DoLog('#subscription error: ' + ErrorMessage);
end;

Book updates will be notified in OnKrakenData event.

 
[
  0,
  {
    "as": [
      [
          "5541.30000",
          "2.50700000",
          "1534614248.123678"
      ],
      [
          "5541.80000",
          "0.33000000",
          "1534614098.345543"
      ],
      [
          "5542.70000",
          "0.64700000",
          "1534614244.654432"
      ]
    ],
    "bs": [
      [
          "5541.20000",
          "1.52900000",
          "1534614248.765567"
      ],
      [
          "5539.90000",
          "0.30000000",
          "1534614241.769870"
      ],
      [
          "5539.50000",
          "5.00000000",
          "1534613831.243486"
      ]
    ]
  },
  "book-100",
  "XBT/USD"
]

Spread

Spread feed to show best bid and ask price for subscribed asset pair. Bid volume and ask volume is part of the
message too.
Subscribe to Spread feed calling SubscribeSpread method.

   
SubscribeSpread(['XBT/USD']);

If subscription is successful, OnKrakenSubscribed event will be called:

   
procedure OnKrakenSubscribed(Sender: TObject;ChannelId: Integer; Pair, Subscription, ChannelName: string;
  ReqID:Integer);
begin
  DoLog('#subscribed: ' + Subscription + ' ' + Pair + ' ' + ChannelName);
end;

352
COMPONENTS

UnSubscribe calling UnSubscribeSpread method:

    
UnSubscribeSpread(['XBT/USD']);

If unsubscription is successful, OnKrakenUnSubscribed event will be called:

   
procedure OnrakenUnSubscribed(Sender: TObject; ChannelId: Integer; Pair, Subscription: string;
  ReqID: Integer);
begin
  DoLog('#unsubscribed: ' + Subscription + ' ' + Pair);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenSubscriptionError event will be called.

  
procedure OnKrakenSubscriptionError(Sender: TObject; ErrorMessage, Pair, Subscription: string;
  ReqID: Integer);
begin
  DoLog('#subscription error: ' + ErrorMessage);
end;

Spread updates will be notified in OnKrakenData event.

 
[
  0,
  [
    "5698.40000",
    "5700.00000",
    "1542057299.545897",
    "1.01234567",
    "0.98765432"
  ],
  "spread",
  "XBT/USD"
]

Other Methods

You can subscribe / unsubscribe to all channels with one method:

  
SubscribeAll(['XBT/USD']);
 
UnSubscribeAll(['XBT/USD']);

OHLC interval value is 1 if all channels subscribed.


 
 
 

Events
OnConnect: when websocket client is connected to client.
OnKrakenConnect: called after successful websocket connection and when server send system status.
OnKrakenSystemStatus: called when system status changes.
OnKrakenSubscribed: called after a successful subscription to a channel.
OnKrakenUnSubscribed: called after a successful unsubscription from a channel.
OnKranSubscriptionError: called if there is an error trying to subscribe / unsubscribe.
OnKrakenData: called every time a channel subscription has an update.

353
COMPONENTS

API Kraken | WebSockets Private API


Connection
URL: wss://ws-auth.kraken.com
 
Once the socket is open you can subscribe to private-data channels by sending an authenticated subscribe request
message.
 

Authentication
The API client must request an authentication "token" via the following REST API endpoint "GetWebSocketsToken"
to connect to WebSockets Private endpoints. The token should be used within 15 minutes of creation. The token
does not expire once a connection to a WebSockets API private message (openOrders or ownTrades) is main­
tained.
In order to get a Websockets Token, an API Key and API Secret must be set in Kraken Options Component, the api
key provided by Kraken in your account

  
Kraken.ApiKey := 'api key';
Kraken.ApiSecret := 'api secret';

Methods

OwnTrades

Get a list of own trades, on first subscription, you get a list of latest 50 trades

  
SubscribeOwnTrades();

Later, you can unsubscribe from OwnTrades, calling UnSubscribeOwnTrades method

  
UnSubscribeOwnTrades();

Response example from server

[
  [
    {
      "TDLH43-DVQXD-2KHVYY": {
        "cost": "1000000.00000",
        "fee": "600.00000",
        "margin": "0.00000",
        "ordertxid": "TDLH43-DVQXD-2KHVYY",
        "ordertype": "limit",
        "pair": "XBT/EUR",
        "postxid": "OGTT3Y-C6I3P-XRI6HX",
        "price": "100000.00000",
        "time": "1560520332.914664",
        "type": "buy",
        "vol": "1000000000.00000000"
      }
    }
  ],
  "ownTrades"
]

354
COMPONENTS

Open Orders

Feed to show all the open orders belonging to the user authenticated API key. Initial snapshot will provide list of all
open orders and then any updates to the open orders list will be sent. For status change updates, such as 'closed',
the fields orderid and status will be present in the payload

  
SubscribeOpenOrders();

Later, you can unsubscribe from OpenOrders, calling UnSubscribeOpenOrders method

  
UnSubscribeOpenOrders();

Response example from server

[
  [
    {
      "OGTT3Y-C6I3P-XRI6HX": {
        "cost": "0.00000",
        "descr": {
          "close": "",
          "leverage": "0:1",
          "order": "sell 0.00001000 XBT/EUR @ limit 9.00000 with 0:1 leverage",
          "ordertype": "limit",
          "pair": "XBT/EUR",
          "price": "9.00000",
          "price2": "0.00000",
          "type": "sell"
        },
        "expiretm": "0.000000",
        "fee": "0.00000",
        "limitprice": "9.00000",
        "misc": "",
        "oflags": "fcib",
        "opentm": "0.000000",
        "price": "9.00000",
        "refid": "OKIVMP-5GVZN-Z2D2UA",
        "starttm": "0.000000",
        "status": "open",
        "stopprice": "0.000000",
        "userref": 0,
        "vol": "0.00001000",
        "vol_exec": "0.00000000"
      }
    }
  ],
  "openOrders"
]

Add Order

Send a new Order to Kraken

  
oKrakenOrder := TsgcWSKrakenOrder.Create;
oKrakenOrder.Pair := 'XBT/USD';
oKrakenOrder._Type := kosBuy;
oKrakenOrder.OrderType := kotMarket;
oKrakenOrder.Volume := 1;
AddOrder(oKrakenOrder);

List of Order parameters

pair = asset pair


type = type of order (buy/sell)
ordertype = order type:
    market
    limit (price = limit price)
    stop-loss (price = stop loss price)
    take-profit (price = take profit price)
    stop-loss-profit (price = stop loss price, price2 = take profit price)
    stop-loss-profit-limit (price = stop loss price, price2 = take profit price)
    stop-loss-limit (price = stop loss trigger price, price2 = triggered limit price)

355
COMPONENTS

    take-profit-limit (price = take profit trigger price, price2 = triggered limit price)
    trailing-stop (price = trailing stop offset)
    trailing-stop-limit (price = trailing stop offset, price2 = triggered limit offset)
    stop-loss-and-limit (price = stop loss price, price2 = limit price)
    settle-position
price = price (optional.  dependent upon ordertype)
price2 = secondary price (optional.  dependent upon ordertype)
volume = order volume in lots
leverage = amount of leverage desired (optional.  default = none)
oflags = comma delimited list of order flags (optional):
    viqc = volume in quote currency (not available for leveraged orders)
    fcib = prefer fee in base currency
    fciq = prefer fee in quote currency
    nompp = no market price protection
    post = post only order (available when ordertype = limit)
starttm = scheduled start time (optional):
    0 = now (default)
    +<n> = schedule start time <n> seconds from now
    <n> = unix timestamp of start time
expiretm = expiration time (optional):
    0 = no expiration (default)
    +<n> = expire <n> seconds from now
    <n> = unix timestamp of expiration time
userref = user reference id.  32-bit signed number.  (optional)
validate = validate inputs only.  do not submit order (optional)
optional closing order to add to system when order gets filled:
    close[ordertype] = order type
    close[price] = price
    close[price2] = secondary price

Response example from server

{
  "descr": "buy 0.01770000 XBTUSD @ limit 4000",
  "event": "addOrderStatus",
  "status": "ok",
  "txid": "ONPNXH-KMKMU-F4MR5V"
}

Cancel Order

Cancel order

  
CancelOrder('Order Id');

Response example from server

{
  "event": "cancelOrderStatus",
  "status": "ok"
}

 
 

356
COMPONENTS

API Kraken | REST Public API


Connection
URL: https://api.kraken.com
 
Kraken Public API doesn't require any authentication.
 

Configuration
The only configuration is enable or not a log for REST HTTP requests. Enable HTTPLogOptions if you want to save
in a text file log all HTTP Requests/Responses
 

Events
  OnKrakenHTTPException: this event is called if there is any exception doing an HTTP Request from REST Api.
 

Methods

GetServerTime

This method is to aid in approximating the skew time between the server and client. Returns Time in Unix format.

{"error":[],"result":{"unixtime":1586705546,"rfc1123":"Sun, 12 Apr 20 15:32:26 +0000"}}

GetAssets

Returns information about Assets

{"error":[],"result":{"ADA":{"aclass":"currency","altname":"ADA","decimals":8,"display_decimals":6}}}}

GetAssetPairs

Returns information about a pair of assets

Kraken.REST_API.GetAssetPairs(['XBTUSD']);

GetTicker

Returns ticker information

Kraken.REST_API.GetTicker(['XBTUSD']);

GetOHLC

Returns Open-High-Low-Close data.

357
COMPONENTS

Kraken.REST_API.GetOHLC('XBTUSD');

GetOrderBook

Returns Array pair name and market depth.

Kraken.REST_API.GetOrderBook('XBTUSD');

GetTrades

Returns recent trade data of a pair.

Kraken.REST_API.GetTrades('XBTUSD');

GetSpread

Returns recent spread data of a pair.

Kraken.REST_API.GetSpread('XBTUSD');

358
COMPONENTS

API Kraken | REST Private API


Connection
URL: https://api.kraken.com
 

Authentication
REST Private API requires an API Key and API Secret, these values are provided by Kraken in your account.

  
Kraken.ApiKey := 'api key';
Kraken.ApiSecret := 'api secret';

Methods

GetAccountBalance

Returns your account balance.

Kraken.REST_API.GetAccountBalance();

GetTradeBalance

Returns information about your trades.

Kraken.REST_API.GetTradeBalance();

GetOpenOrders

Returns a list of open orders.

Kraken.REST_API.GetOpenOrders();

GetClosedOrders

Returns a list of closed orders.

Kraken.REST_API.GetClosedOrders();

QueryOrders

Query information about an order.

Kraken.REST_API.QueryOrders('1234');

359
COMPONENTS

GetTradesHistory

Returns an array of trade info.

Kraken.REST_API.GetTradesHistory();

QueryTrades

Query information about a trade.

Kraken.REST_API.QueryTrades('1234');

GetOpenPositions

Returns position info.

Kraken.REST_API.GetOpenPositions('1234');

GetLedgers

Returns associative array of ledgers info.

Kraken.REST_API.GetLedgers();

QueryLedgers

Returns associative array of ledgers info.

Kraken.REST_API.QueryLedgers('1234');

GetTradeVolume

Returns trade volume info.

Kraken.REST_API.GetTradeVolume();

AddExport

Adds a new report export.

Kraken.REST_API.AddExport('Report All Trades');

ExportStatus

Get Status of reports

Kraken.REST_API.ExportStatus();

360
COMPONENTS

RetrieveExport

Get Report by report id.

Kraken.REST_API.RetrieveExport('GOCO');

RemoveExport

Remove Report by report id.

Kraken.REST_API.RemoveExport('GOCO');

Add Order

Adds a new order

pair = asset pair


type = type of order (buy/sell)
ordertype = order type:
    market
    limit (price = limit price)
    stop-loss (price = stop loss price)
    take-profit (price = take profit price)
    stop-loss-profit (price = stop loss price, price2 = take profit price)
    stop-loss-profit-limit (price = stop loss price, price2 = take profit price)
    stop-loss-limit (price = stop loss trigger price, price2 = triggered limit price)
    take-profit-limit (price = take profit trigger price, price2 = triggered limit price)
    trailing-stop (price = trailing stop offset)
    trailing-stop-limit (price = trailing stop offset, price2 = triggered limit offset)
    stop-loss-and-limit (price = stop loss price, price2 = limit price)
    settle-position
price = price (optional.  dependent upon ordertype)
price2 = secondary price (optional.  dependent upon ordertype)
volume = order volume in lots
leverage = amount of leverage desired (optional.  default = none)
oflags = comma delimited list of order flags (optional):
    viqc = volume in quote currency (not available for leveraged orders)
    fcib = prefer fee in base currency
    fciq = prefer fee in quote currency
    nompp = no market price protection
    post = post only order (available when ordertype = limit)
starttm = scheduled start time (optional):
    0 = now (default)
    +n = schedule start time n seconds from now
    n = unix timestamp of start time
expiretm = expiration time (optional):
    0 = no expiration (default)
    +n = expire n seconds from now
    n = unix timestamp of expiration time
userref = user reference id.  32-bit signed number.  (optional)
validate = validate inputs only.  do not submit order (optional)
optional closing order to add to system when order gets filled:
    close[ordertype] = order type
    close[price] = price
    close[price2] = secondary price

oKrakenOrder := TsgcWSKrakenOrder.Create;
oKrakenOrder.Pair := 'XBT/USD';
oKrakenOrder._Type := kosBuy;
oKrakenOrder.OrderType := kotMarket;
oKrakenOrder.Volume := 1;
Kraken.REST_API.AddOrder(oKrakenOrder);

CancelOrder

Cancels an open order by id

Kraken.REST_API.CancelOrder('1234');

361
COMPONENTS

API Kraken Futures


Kraken Futures
 

Overview
The REST API allows to securely access the methods of your Kraken Futures account. Examples of REST API
Methods:
 
• request current or historical price information
• check your account balance and PnL
• your margin parameters and estimated liquidation thresholds
• place or cancel orders (individually or in batch)
• see your open orders
• open positions or trade history
• request a digital asset withdrawal
 
These methods are called "endpoints" and are explained in REST API section.
 
The Websocket API allows to securely establish a communication channel to the Kraken Futures platform to re­
ceive information in real time. This allows listening to updates instead of continuously sending requests. These
channels are called subscriptions.
 
Some of the endpoints allow performing sensitive tasks, such initiating a digital asset withdrawal. To access these
endpoints securely, the API uses encryption techniques developed by the National Security Agency.
 

Configuration
In order to use the API, you need to generate a pair of unique API keys (if you want access to private APIs):
 
1. Sign in to your Kraken Futures account.
2. Click on your name on the upper-right corner.
3. Select "Settings" from the drop-down menu.
4. Select the "Create Key" tab in the API panel.
5. Press the "Create Key" button.
6. View your Public and Private keys and record them somewhere safe.
 
Copy the Public and Private Keys to the KrakenOptions property of the component.
 
KrakenOptions.ApiKey
KrakenOptions.ApiSecret
 
 

APIs supported
 
• WebSockets Public API: connects to a public WebSocket server.
• WebSockets Private API: connects to a private WebSocket server and requires an API Key and API Secret
to Authenticate against server.
• REST Public API: connects to a public REST server.
• REST Private API: connects to a public REST server and requires an API Key and API Secret to Authenti­
cate against server.

362
COMPONENTS

API Kraken Futures | WebSockets Public API


Connection
URL: wss://futures.kraken.com/ws/v1
 
Once the socket is open you can subscribe to a public channel by sending a subscribe request message.
 
 

Methods

Ticker

This endpoint returns current market data for all currently listed Futures contracts and indices. Authentication is not
required.
Subscribe to a ticker calling SubscribeTicker method:

SubscribeTicker(['PI_XBTUSD']);

If subscription is successful, OnKrakenFuturesSubscribed event will be called:

procedure OnKrakenFuturesSubscribed(Sender: TObject; Feed, ProductId: string);


begin
  DoLog('#subscribed: ' + Feed + ' ' + ProductId);
end;

UnSubscribe calling UnSubscribeTicker method:

UnSubscribeTicker(['PI_XBTUSD']);

If unsubscription is successful, OnKrakenFuturesUnSubscribed event will be called:

procedure OnKrakenFuturesUnSubscribed(Sender: TObject; Feed, ProductId: string);


begin
  DoLog('#unsubscribed: ' + Feed + ' ' + ProductId);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenFuturesError event will be called.

procedure OnKrakenFuturesError(Sender: TObject; Error: string);


begin
  DoLog('#error: ' + Error);
end;

Ticker updates will be notified in OnKrakenData event.

{    "result":"success",
  "tickers":[ 
       
{
"tag": "perpetual",
"pair":
"XBT:USD",
"symbol": "pi_xbtusd",
"markPrice":
9520.2,

363
COMPONENTS

"bid": 9520,
"bidSize": 30950,
"ask":
9520.5,
"askSize": 3779,
"vol24h": 68238712,
"openInterest":
29308193,
"open24h": 10137,
"last": 9521,
"lastTime":
"2020-06-03T08:14:26.624Z",
"lastSize": 1,
"suspended":
false,
"fundingRate": 4.943012455e-9,
"fundingRatePrediction":
4.414499215e-9
}
{
"tag": "quarter",
"pair":
"XBT:USD",
"symbol": "fi_xbtusd_200925",
"markPrice":
9659.8,
"bid": 9659.5,
"bidSize": 6480,
"ask":
9660,
"askSize": 17100,
"vol24h": 4562580,
"openInterest":
3573325,
"open24h": 10370.5,
"last": 9660,
"lastTime":
"2020-06-03T08:10:37.800Z",
"lastSize": 5000,
"suspended":
false
},
{
"symbol": "in_xbtusd",
"last":
9519,
"lastTime": "2020-06-03T08:14:49.000Z"
}
],
"serverTime":
"2020-06-03T08:14:49.865Z"
}

Trade

The trade feed returns information about executed trades


Subscribe to Trade feed calling SubscribeTrade method.

 
SubscribeTrade(['PI_XBTUSD']);

If subscription is successful, OnKrakenFuturesSubscribed event will be called:

364
COMPONENTS

 
procedure OnKrakenFuturesSubscribed(Sender: TObject; Feed, ProductId: string);
begin
  DoLog('#subscribed: ' + Feed + ' ' + ProductId);
end;

UnSubscribe calling UnSubscribeTrade method:

 
UnSubscribeTrade(['PI_XBTUSD']);

If unsubscription is successful, OnKrakenFuturesUnSubscribed event will be called:

  
procedure OnrakenFuturesUnSubscribed(Sender: TObject; Feed, ProductId: string);
begin
  DoLog('#unsubscribed: ' + Feed + ' ' + ProductId);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenFuturesError event will be called.

   
procedure OnKrakenFuturesSubscriptionError(Sender: TObject; Error: string);
begin
  DoLog('#error: ' + Error);
end;

Trade updates will be notified in OnKrakenData event.

{  "feed": "trade_snapshot",
  "product_id": 
"PI_XBTUSD",
  "trades": [
{
   "feed": 
"trade",
   "product_id": "PI_XBTUSD",
   "uid": 
"caa9c653-420b-4c24-a9f1-462a054d86f1",
   "side": 
"sell",
   "type": "fill",
   "seq": 
655508,
   "time": 1612269657781,
   "qty": 
440,
   "price": 34893
},
{
   "feed": 
"trade",
   "product_id": "PI_XBTUSD",
   "uid": 
"45ee9737-1877-4682-bc68-e4ef818ef88a",
   "side": 
"sell",
   "type": "fill",
   "seq": 
655507,
   "time": 1612269656839,
   "qty": 
9643,
   "price": 34891
}
  ]
}

365
COMPONENTS

Book

This feed returns information about the order book.


Subscribe to a Book calling SubscribeBook method, you must pass the Symbol.

  
SubscribeBook(['PI_XBTUSD']);

If subscription is successful, OnKrakenFuturesSubscribed event will be called:

   
procedure OnKrakenFuturesSubscribed(Sender: TObject; Feed, ProductId: string);
begin
  DoLog('#subscribed: ' + Feed + ' ' + ProductId);
end;

UnSubscribe calling UnSubscribeBook method:

    
UnSubscribeBook(['PI_XBTUSD']);

If unsubscription is successful, OnKrakenFuturesUnSubscribed event will be called:

  
procedure OnKrakenFuturesUnSubscribed(Sender: TObject; Feed, ProductId: string);
begin
  DoLog('#unsubscribed: ' + Feed + ' ' + ProductId);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenFuturesError event will be called.

   
procedure OnKrakenFuturesError(Sender: TObject; Error: string);
begin
  DoLog('#error: ' + Error);
end;

Book updates will be notified in OnKrakenData event.

{
"feed": "book_snapshot",
"product_id":
"PI_XBTUSD",
"timestamp": 1612269825817,
"seq":
326072249,
"tickSize": null,
"bids": [{
"price":
34892.5,
"qty": 6385
},
{
"price": 34892,
"qty":
10924
}
],
"asks": [{
"price": 34911.5,
"qty":
20598
},
{
"price": 34912,
"qty": 2300
}
]
}

366
COMPONENTS

Ticker Lite

The ticker lite feed returns ticker information about listed products.
Subscribe to Spread feed calling SubscribeTickerLite method.

   
SubscribeTickerLite(['PI_XBTUSD']);

If subscription is successful, OnKrakenFuturesSubscribed event will be called:

   
procedure OnKrakenFuturesSubscribed(Sender: TObject; Feed, ProductId: string);
begin
  DoLog('#subscribed: ' + Feed + ' ' + ProductId);
end;

UnSubscribe calling UnSubscribeTickerLite method:

    
UnSubscribeTickerLite(['PI_XBTUSD']);

If unsubscription is successful, OnKrakenFuturesUnSubscribed event will be called:

   
procedure OnKrakenFuturesUnSubscribed(Sender: TObject; Feed, ProductId: string);
begin
  DoLog('#unsubscribed: ' + Feed + ' ' + ProductId);
end;

If there is an error while trying to subscribe / unsubscribe, OnKrakenFuturesError event will be called.

  
procedure OnKrakenFuturesError(Sender: TObject; Error: string);
begin
  DoLog('#error: ' + Error);
end;

Spread updates will be notified in OnKrakenData event.

{  "feed": "ticker_lite",
  "product_id": 
"PI_XBTUSD",
  "bid": 34932,
  "ask": 
34949.5,
  "change": 3.3705205220015966,
  "premium": 
0.1,
  "volume": 264126741,
  "tag": 
"perpetual",
  "pair": "XBT:USD",
  "dtm": 
0,
  "maturityTime": 0
}
{
"feed":"ticker_lite",
"product_id":"FI_ETHUSD_210625",
"bid":1753.45,
"ask":1760.35,
"change":13.448175559936647,
"premium":9.1,
"volume":6899673.0,
"tag":"semiannual",
"pair":"ETH:USD",
"dtm":141,
"maturityTime":1624633200000
}

367
COMPONENTS

HeartBeat

The heartbeat feed publishes a heartbeat message at timed intervals.

  
SubscribeHeartBeat();
 
UnSubscribeHeartBeat();

 
 
 

Events
OnConnect: when websocket client is connected to client.
OnKrakenFuturesConnect: called after successful websocket connection and when server send system status.
OnKrakenFuturesSubscribed: called after a successful subscription to a channel.
OnKrakenFuturesUnSubscribed: called after a successful unsubscription from a channel.
OnKrakenFuturesError: called if there is any error while subscribing/unsubscribing.
OnKrakenData: called every time a channel subscription has an update.

368
COMPONENTS

API Kraken Futures | WebSockets Private


API
Connection
URL: wss://futures.kraken.com/ws/v1
 

Authentication
The subscribe and unsubscribe requests to WebSocket private feeds require a signed challenge message with the
user api_secret.
The challenge is obtained as is shown in Section WebSocket API Public (using the api_key).
Authenticated requests must include both the original challenge message (original_challenge) and the signed
(signed_challenge) in JSON format.
In order to get a Websockets Challenge, an API Key and API Secret must be set in Kraken Options Component,
the api key provided by Kraken in your account

  
Kraken.ApiKey := 'api key';
Kraken.ApiSecret := 'api secret';

Methods

Open Orders Verbose

This subscription feed publishes information about user open orders. This feed adds extra information about all the
post-only orders that failed to cross the book.

  
SubscribeOpenOrdersVerbose();

Later, you can unsubscribe from OpenOrdersVerbose, calling UnSubscribeOpenOrdersVerbose method

  
UnSubscribeOpenOrdersVerbose();

Response example from server

{        'feed':'open_orders_verbose_snapshot',   'account':'0f9c23b8-63e2-40e4-9592-6d5aa57c12
        {           'instrument':'PI_XBTUSD',         'time':1567428848005,         'last_updat

Open Positions

This subscription feed publishes the open positions of the user account.

  
SubscribeOpenPositions();

Later, you can unsubscribe from OpenPositions, calling UnSubscribeOpenPositions method

  
UnSubscribeOpenPositions();

Response example from server

369
COMPONENTS

{
    "feed": "open_positions",
    "account": "DemoUser",
    "positions": [{
        "instrument": "fi_xbtusd_180316",
        "balance": 2000.0,
        "entry_price": 11675.86541981,
        "mark_price": 11090.0,
        "index_price": 12290.550000000001,
        "pnl": -0.00905299
    }]
}

Account Log

This subscription feed publishes account information.

  
SubscribeAccountLog();

Later, you can unsubscribe from AccountLog, calling UnSubscribeAccountLog method

  
UnSubscribeAccountLog();

Response example from server

{
    'feed': 'account_log_snapshot',
    'logs': [{
                'id': 1690,
                'date': '2019-07-11T08:00:00.000Z',
                'asset': 'bch',
                'info': 'funding 
                rate change ','
                booking_uid ':'
                86 fdc252 - 1 b6e - 40 ec - ac1d - c7bd46ddeebf ','
                margin_account ':'
                f - bch: usd ','
                old_balance ':0.01215667051,'
                new_balance ':0.01215736653,'
                old_average_entry_price ':0.0,'
                new_average_entry_price ':0.0,'
                trade_price ':0.0,'
                mark_price ':0.0,'
                realized_pnl ':0.0,'
                fee ':0.0,'
                execution ':'
                ','
                collateral ':'
                bch ','
                funding_rate ':-8.7002552653e-08,'
                realized_funding ':6.9602e-07}]
}

Fills

This subscription feed publishes fills information.

  
SubscribeFills();

Later, you can unsubscribe from Fills, calling UnSubscribeFills method

  
UnSubscribeFills();

370
COMPONENTS

Response example from server

 
   "feed":"fills_snapshot",
 
    "account":"DemoUser",
 
    "fills":[
 
            {
 
            "instrument":"FI_XBTUSD_200925",
 
            "time":1600256910739,
 
            "price":10937.5,
 
            "seq":36,
 
            "buy":true,
 
            "qty":5000.0,
 
            "order_id":"9e30258b­5a98­4002­968a­5b0e149bcfbf",
 
            "fill_id":"cad76f07­814e­4dc6­8478­7867407b6bff",
 
            "fill_type":"maker",
 
            "fee_paid":­0.00009142857,
 
            "fee_currency":"BTC"
 
           }]
 
}
 

Open Orders

This subscription feed publishes information about user open orders.

  
SubscribeOpenOrders();

Later, you can unsubscribe from OpenOrders, calling UnSubscribeOpenOrders method

  
UnSubscribeOpenOrders();

Response example from server

 
"feed": "open_orders_snapshot",
 
"account": "e258dba9-4dd4-4da5-bfef-75beb91c098e",
 
"orders": [
 
      {
 

371
COMPONENTS

       "instrument": "PI_XBTUSD",
 
       "time": 1612275024153,
 
       "last_update_time": 1612275024153,
 
       "qty": 1000,
 
       "filled": 0,
 
       "limit_price": 34900,
 
       "stop_price": 13789,
 
       "type": "stop",
 
       "order_id": "723ba95f-13b7-418b-8fcf-ab7ba6620555",
 
       "direction": 1,
 
       "reduce_only": false,
 
       "triggerSignal": "last"
 
     }
 
   ]
 
}
 

Account Balance And Margins

This subscription feed returns balance and margin information for the client's account.

  
SubscribeAccountBalanceAndMargins();

Later, you can unsubscribe from AccounBalance, calling UnSubscribeAccountBalanceAndMargins method

  
UnSubscribeAccountBalanceAndMargins();

Response example from server

 
"feed": "account_balances_and_margins",
 
"account": "DemoUser",
 
"margin_accounts": [
 
    {
 
    "name": "xbt",
 
     "balance": 0,
 
      "pnl": 0,
 
    "funding": 0,
 
    "pv": 0,

372
COMPONENTS

 
    "am": 0,
 
    "im": 0,
 
    "mm": 0
 
    },
 
    {
 
    "name": "f-xbt:usd",
 
     "balance": 9.99730211055,
 
     "pnl": -0.00006034858674327812,
 
    "funding": 0,
 
    "pv": 9.997241761963258,
 
    "am": 9.99666885201038,
 
    "im": 0.0005729099528781564,
 
    "mm": 0.0002864549764390782
 
    },
 
   ],
 
   "seq": 14
 
}
 

Notifications

This subscription feed publishes notifications to the client.

  
SubscribeNotifications();

Later, you can unsubscribe from Notifications, calling UnSubscribeNotifications method

  
UnSubscribeNotifications();

Response example from server

{  

 
   "feed":"notifications_auth",
 
   "notifications":[  
 
      {  
 
         "id":5,
 
         "type":"market",
 
         "priority":"low",
 

373
COMPONENTS

         "note":"A note describing the notification.",


 
         "effective_time":1520288300000
 
      },
 
      ...
 
   ]
 
}
 

374
COMPONENTS

API Kraken Futures | REST Public API


Connection
URL: https://futures.kraken.com/derivatives/api/v3
 
Kraken Futures Public API doesn't require any authentication.
 

Configuration
The only configuration is enable or not a log for REST HTTP requests. Enable HTTPLogOptions if you want to save
in a text file log all HTTP Requests/Responses
 

Events
  OnKrakenHTTPException: this event is called if there is any exception doing an HTTP Request from REST Api.
 

Methods

GetFeeSchedules

This endpoint lists all fee schedules. Authentication is not required.

KrakenFutures.REST_API.GetFeeSchedules();

Order Book

This endpoint returns the entire non-cumulative order book of currently listed Futures contracts.

KrakenFutures.REST_API.GetOrderBook('PI_XBTUSD');

Tickers

This endpoint returns current market data for all currently listed Futures contracts and indices.

KrakenFutures.REST_API.GetTickers();

Instruments

This endpoint returns specifications for all currently listed Futures contracts and indices.

KrakenFutures.REST_API.GetInstruments();

375
COMPONENTS

History

This endpoint returns the last 100 trades from the specified lastTime value - if no value specified will return the last
100 trades. is endpoint only returns trade history for a maximum of 7 days from the time it is called or since
last .trading engine release (whichever is sooner).

KrakenFutures.REST_API.GetHistory('PI_XBTUSD');

376
COMPONENTS

API Kraken Futures | REST Private API


Connection
URL: https://futures.kraken.com/derivatives/api/v3
 

Authentication
REST Private API requires an API Key and API Secret, these values are provided by Kraken in your account.

  
Kraken.ApiKey := 'api key';
Kraken.ApiSecret := 'api secret';

Methods

EditOrderByOrderId

This endpoint allows editing an existing order for a currently listed Futures contract.
 
aOrderId: ID of the order you wish to edit
aSize: The size associated with the order
aLimitPrice: The limit price associated with the order.
aStopPrice: The stop price associated with a stop order. Required if old Order Type is Stop.

KrakenFutures.REST_API.EditOrderByOrderId('Order_Id', 2, 1000);

EditOrderByCliOrderId

This endpoint allows editing an existing order for a currently listed Futures contract.
 
aCliOrderId: The order identity that is specified from the user. It must be globally unique.
aSize: The size associated with the order
aLimitPrice: The limit price associated with the order.
aStopPrice: The stop price associated with a stop order. Required if Order Type is Stop.

KrakenFutures.REST_API.EditOrderByCliOrderId('Cli_Order_Id', 2, 1000);

SendMarketOrder

This endpoint allows to send a Market Order.


 
aSide: The direction of the order: buy or sell.
aSymbol: The symbol of the futures
aSize: The size associated with the order.

KrakenFutures.REST_API.SendMarketOrder(kosfBuy, 'PI_XBTUSD', 1);

377
COMPONENTS

SendLimitOrder

This endpoint allows to send a Limit Order.


 
aSide: The direction of the order: buy or sell.
aSymbol: The symbol of the futures
aSize: The size associated with the order.
aLimitPrice: The limit price associated with the order.

KrakenFutures.REST_API.SendLimitOrder(kosfBuy, 'PI_XBTUSD', 1, 1000);

SendStopOrder

This endpoint allows to send a Stop Order.


 
aSide: The direction of the order: buy or sell.
aSymbol: The symbol of the futures
aSize: The size associated with the order.
aStopPrice: The stop price associated with a stop order.
aLimitPrice: The limit price associated with the order.

KrakenFutures.REST_API.SendStopOrder(kosfBuy, 'PI_XBTUSD', 1, 1000, 900);

SendTakeProfitOrder

This endpoint allows to send a Take Profit Order.


 
aSide: The direction of the order: buy or sell.
aSymbol: The symbol of the futures
aSize: The size associated with the order.
aStopPrice: The stop price associated with a stop order.
aLimitPrice: The limit price associated with the order.

KrakenFutures.REST_API.SendTakeProfitOrder(kosfBuy, 'PI_XBTUSD', 1, 1000, 900);

SendOrder

This endpoint allows sending a limit, stop, take profit or immediate-or-cancel order for a currently listed Futures
contract.
 
OrderType: select one of the following kotfLMT, kotfPOST, kotfMKT, kotfSTP, kotfTAKE_PROFIT, kotfIOC
Symbol: The symbol of the futures
Side: The direction of the order (buy or sell).
Size: The size associated with the order.
StopPrice: The stop price associated with a stop order.
LimitPrice: The limit price associated with the order.
TriggerSignal: If placing a Stop or TakeProfit order, the signal used for trigger, select one of the following kots­
Mark, kotsIndex, kotsLast
CliOrderId: The order identity that is specified from the user. It must be globally unique.
ReduceOnly: Set as true if you wish the order to only reduce an existing position. Any order which increases an
existing position will be rejected. Default false.

oOrder := TsgcHTTPKrakenFuturesOrder.Create;
Try
  oOrder.Side := kosfBuy;
  oOrder.Symbol := 'PI_XBTUSD';
  oOrder.OrderType := kotfMKT;
  oOrder.Size := 1;
  KrakenFutures.REST_API.SendOrder(oOrder);  
Finally

378
COMPONENTS

  oOrder.Free;
End;

CancelOrderByOrderId

This endpoint allows cancelling an open order for a Futures contract.


 
aOrderId: ID of the order you wish to edit

KrakenFutures.REST_API.CancelOrderByOrderId('Order_Id');

CancelOrderByCliOrderId

This endpoint allows cancelling an open order for a Futures contract.


 
aCliOrderId: The order identity that is specified from the user. It must be globally unique.

KrakenFutures.REST_API.CancelOrderByCliOrderId('Cli_Order_Id');

GetFills

This endpoint returns information on filled orders for all futures contracts.
 
aLastFillDate: If not provided, returns the last 100 fills in any futures contract. If provided, returns the 100 entries
before lastFillTime.

KrakenFutures.REST_API.GetFills('2020-07-22T13:45:00.000Z');

Transfer

This endpoint allows you to transfer funds between two margin accounts with the same collateral currency, or be­
tween a margin account and your cash account.
 
aFromAcocunt: The name of the cash or margin account to move funds from.
aToAcocunt: The name of the cash or margin account to move funds to.
aUnit: The unit to transfer.
aAmount: The amount to transfer.

KrakenFutures.REST_API.Transfer('FI_XBTUSD', 'cash', 'xbt', 1.5);

GetOpenPositions

This endpoint returns the size and average entry price of all open positions in Futures contracts. This includes Fu­
tures contracts that have matured but have not yet been settled.

KrakenFutures.REST_API.GetOpenPositions();

GetNotifications

This endpoint provides the platform's notifications.

KrakenFutures.REST_API.GetNotifications();

379
COMPONENTS

GetAccounts

This endpoint returns key information relating to all your Kraken Futures accounts which may either be cash ac­
counts or margin accounts. This includes digital asset balances, instrument balances, margin requirements, margin
trigger estimates and auxiliary information such as available funds, PnL of open positions and portfolio value.

KrakenFutures.REST_API.GetAccounts();

CancelAllOrders

This endpoint allows cancelling an open order for a Futures contract.


 
Symbol: A futures product to cancel all open orders (optional)

KrakenFutures.REST_API.CancelAllOrders();

CancelAllOrdersAfter

This endpoint provides a Dead Man's Switch mechanism to protect the client from network malfunctions. The client
can send a request with a timeout in seconds which will trigger a countdown timer that will cancel all client orders
when timeout expires.
 
aTimeout: The timeout specified in seconds.

KrakenFutures.REST_API.CancelAllOrdersAfter(60);

GetOpenOrders

This endpoint returns information on all open orders for all Futures contracts.

KrakenFutures.REST_API.OpenOrders();

GetHistoricalOrders

This endpoint returns historical orders made on an account.


 
aSince: The DateTime Since
aBefore: The DateTime Before
aSort: "asc" for ascending sort "desc" for descending
aContinuationToken: Continuation token provided from a prior response which can be used in call to return the
next set of available results

KrakenFutures.REST_API.GetHistoricalOrders(Now, Now - 5);

GetHistoricalTriggers

This endpoint returns allows historical triggers made on an account.


 
aSince: The DateTime Since
aBefore: The DateTime Before
aSort: "asc" for ascending sort "desc" for descending
aContinuationToken: Continuation token provided from a prior response which can be used in call to return the
next set of available results

380
COMPONENTS

KrakenFutures.REST_API.GetHistoricalTriggers(Now, Now - 5);

GetHistoricalExecutions

This endpoint returns allows historical executions made on an account.


 
aSince: The DateTime Since
aBefore: The DateTime Before
aSort: "asc" for ascending sort "desc" for descending
aContinuationToken: Continuation token provided from a prior response which can be used in call to return the
next set of available results

KrakenFutures.REST_API.GetHistoricalExecutions(Now, Now - 5);

WithdrawalToSpotWallet

This endpoint allows submitting a request to withdraw digital assets from a Kraken Futures wallet to your Kraken
Spot wallet.
 
aCurrency: The digital asset that shall be withdrawn, e.g. xbt or xrp.
aAmount: The amount of currency that shall be withdrawn.

KrakenFutures.REST_API.WithdrawalToSpotWallet('xbt', 1000);

GetFeeScheduleVolumes

This endpoint returns your 30-day USD volume.

KrakenFutures.REST_API.GetFeeScheduleVolumes();

GetAccountLogCSV

This endpoint allows clients to download a csv file of their account logs.

KrakenFutures.REST_API.GetAccountLogCSV();

381
COMPONENTS

API FTX
FTX
 

APIs supported
• WebSockets API: connect to a public websocket server and provides real-time market data updates.
• REST API: The REST API has endpoints for account and order management as well as public market data.
 
 

Most common uses


• WebSockets API
• How Connect WebSocket API
• How Subscribe WebSocket Channel
• REST API
• How Get Market Data
• How Use Private REST API
• How Place Orders
 

WebSockets API
The websocket feed provides real-time market data updates for orders and trades. The websocket feed has some
public channels like ticker, trades... and some private channels which require an API Key and API Secret like Fills
and Orders.
The websocket feed uses a bidirectional protocol, which encodes all messages as JSON objects. All messages
have a type attribute that can be used to handle the message appropriately.
 
You can subscribe to the following Public channels:
 
Argu­
Method Description
ments
aMarket: The ticker channel provides
SubscribeT­
name of the the latest best bid and offer
icker
market market data.
The markets channel provides
information on the full set of
tradable markets and their
specifications. After subscrip­
Subscribe­
  tion and whenever any market
Markets
lists, delsists, or changes, you
will receive a partial message
with information on all mar­
kets.
aMarket: The trades channel provides
Subscribe­
name of the data on all trades in the mar­
Trades
market ket.
The orderbook channel pro­
Sub­ aMarket:
vides data about the
scribeOrder­ name of the
orderbook's best 100 orders
books market
on either side.

382
COMPONENTS

The grouped orderbooks


Sub­ aMarket:
channel supplies orderbook
scribeGroupe­ name of the
data with grouped (collapsed)
dOrderbooks market
prices.
 
Some of this channels requires Authenticate against FTX servers. So first request your API keys in your FTX Ac­
count and then set the values in the property FTX of the component:
 
• ApiKey
• ApiSecret
• SubAccount (optional)
 
When the WebSocket client connects to FTX servers, if detect the ApiKey and ApiSecret are defined automatically
try to login to the FTX Server. If successful, you can subscribe to the following Private Channels:
 
Argu­
Method Description
ments
Sub­ This channel streams your fills
 
scribeFills across all markets.
This channel streams updates
Sub­
  to your orders across all mar­
scribeOrders
kets.
 
 

REST API

Public Endpoints

Some of the REST Channels are public, so you don't need to configure the API Keys.
 
Markets
 
This section covers all types of markets on FTX: spot, perpetual futures, expiring futures, and MOVE contracts. Ex­
amples for each type are BTC/USD, BTC-PERP, BTC-0626, and BTC-MOVE-1005.
 
Argu­
Method Description
ments
GetMar­
   
kets
aMarket:
GetMar­
name of the  
ket
market
aMarket:
GetOrder­
name of the  
book
market
aMarket:
Get­
name of the  
Trades
market
Historical prices of expired futures
GetHis­ aMarket:
can be retrieved with this end point
torical­ name of the
but make sure to specify start time
Prices market
and end time.
 
 
Futures
 

383
COMPONENTS

This section covers all types of futures on FTX: perpetual, expiring, and MOVE. Examples for each type are BTC-
PERP, BTC-0626, and BTC-MOVE-1005.
 
Argu­
Method Description
ments
GetFutures    
aFuture:
GetFuture name of the  
future
aFuture:
GetFutureStats name of the  
future
GetFundin­
   
gRates
Note that this only applies
aFuture:
to index futures, e.g. ALT/
GetIndexWeights name of the
MID/SHIT/EXCH/DRAG­
future
ON.
GetExpiredFu­ Returns the list of all ex­
 
tures pired futures.
aFuture:
GetHistoricalIn­
name of the  
dex
future
 

Private Endpoints

Private endpoints are available for order management, and account management.
Before being able to sign any requests, you must create an API key via the FTX website. The API key will be
scoped to a specific profile. Upon creating a key you will have 2 pieces of information which you must remember:
 
• Key
• Secret
• SubAccount (optional)
 
Private endpoints require your local time is synchronized with FTX server time, if there is a difference too high,
you will get a 401 Unauthorized error
 
{"success":false:"error":"Not logged in"}
 
Account
 
Method Arguments Description
GetAccount    
GetAccoun­
   
tHistory
ChangeAc­ aLeverage: desired
countLever­ account­wide lever­  
age age setting
 
 
Subaccounts
 
Method Arguments Description
GetAllSub­
   
accounts

384
COMPONENTS

CreateSub­ aNickName: name of the subac­
 
account count
ChangeSub­ aOldNickname: current nickname of
account­ subaccount aNewNickname: new  
Name nickname of subaccount
DeleteSub­ aNickName: name of the subac­
 
account count
GetSubac­
aNickName: name of the subac­
countBal­  
count
ances
aCoin: example XRP aSize: size of
transfer aSource: name of the
TransferBe­
source subaccount. "main" for the
tweenSub­  
main account. aDestination: name
accounts
of the destination subaccount.
"main" for the main account.  
 
 
Wallets
 
De­
Method Arguments scrip­
tion
GetCoins    
GetBal­
   
ances
GetBal­
ancesAl­    
lAccounts
GetDeposi­ aCoin: USDT aMethod: optional, for coins available
 
tAddress on different blockchains, example: USDT
GetDe­ aStartTime: optional; minimum time of items to return,
positHisto­ in Unix time aEndTime: optional; maximum time of  
ry items to return, in Unix time
GetWith­ aStartTime: optional; minimum time of items to return,
drawalHis­ in Unix time aEndTime: optional; maximum time of  
tory items to return, in Unix time
aCoin: coin to withdraw. aSize: amount to withdraw.
aAddress: address to send to (example:
Request­ 0x83a127952d266A6eA306c40Ac62A4a70668FE3BE)
 
Withdrawal aTag: optional. aPassword: optional, withdrawal pass­
word if it is required for your account aCode: optional;
2fa code if it is required for your account
This
end­
point
pro­
aStartTime: optional; minimum time of items to return, vides
GetAir­
in Unix time aEndTime: optional; maximum time of you
Drops
items to return, in Unix time with
up­
dates
to
your

385
COMPONENTS

AMPL
bal­
ances
based
on
AMPL
re­
bases.
aCoin: coin id. aSize: amount. aAddress: address to
GetWith­ withdraw (example:
 
drawalFees 0x83a127952d266A6eA306c40Ac62A4a70668FE3BE)
aTag: optional.
This
end­
point
pro­
vides
Get­
you
SavedAd­ aCoin: optional, filters saved addresses by coin;
with
dresses
your
saved
ad­
dress­
es
aCoin: coin id. aAddress: address to create (exam­
Create­ ple:
SavedAd­ 0x83a127952d266A6eA306c40Ac62A4a70668FE3BE)  
dresses aAddressName: string aIsPrimetrust: boolean aTag:
optional
Delete­
SavedAd­ aSavedAddressId: id of the saved address.  
dresses
 
 
 
Orders
 
Descrip­
Method Arguments
tion
aMarket: name
GetOpenOrders  
of the market
aMarket: name
GetOrderHistory  
of the market
aMarket: name
of the market
aTriggerOrder:
GetOpenTriggerOrders [fttotNone, fttot­  
Stop,
fttotTrailing_Stop,
fttotTake_Profit]
aOrderId: num­
GetTriggerOrderTriggers ber that identifi­  
cates the Order.

386
COMPONENTS

aMarket: name
GetTriggerOrderHistory  
of the market
Places a
new order.
aOrder: Ts­ Passes a Ts­
PlaceOrder gcHTTPFTX­ gcHTTPFTX­
Order instance Order object
as a para­
meter.
aMarket: name
of the market Places a
PlaceMarketOrder aSide: buy or new Market
sell aSize: size order.  
of the order
aMarket: name
of the market
aSide: buy or Places a
PlaceLimitOrder sell aSize: size new Limit
of the order Order
aPrice: price lim­
it of the order
Places a
new trigger
aOrder: Ts­ order. Pass­
gcHTTPFTXTrig­ es a Ts­
PlaceTriggerOrder
gerOrder in­ gcHTTPFTX­
stance TriggerOrder
object as a
parameter.
aMarket: name
of the market
aSide: buy or
sell aSize: size
of the order
aTriggerPrice:
PlaceTriggerStopOrder trigger price  
aOrderPrice: op­
tional, order type
is limit if has val­
ue greater than
zero, otherwise
market.
aMarket: name
of the market
aSide: buy or
sell aSize: size
PlaceTriggerTrailingStopOrder of the order  
aTrailValue:
negative for
"sell", positive for
"buy"
aMarket: name
PlaceTriggerTakeProfitOrder of the market  
aSide: buy or

387
COMPONENTS

sell aSize: size


of the order
aTriggerPrice:
trigger price
aOrderPrice: op­
tional, order type
is limit if has val­
ue greater than
zero, otherwise
market.
aOrderId: num­
ber that identifi­
cates the Order.
ModifyOrder aPrice: price lim­  
it of the order
aSize: size of the
order
aOrderClientId:
string that identi­
ficates the Order.
ModifyOrderByClientId aPrice: price lim­  
it of the order
aSize: size of the
order
aOrderId: num­
ber that identifi­
cates the Order.
aSize: size of the
ModifyTriggerOrder_StopLoss order aTrigger­  
Price: trigger
price aOrder­
Price: order
price
aOrderId: num­
ber that identifi­
cates the Order.
aSize: size of the
ModifyTriggerOrder_TakeProfit order aTrigger­  
Price: trigger
price aOrder­
Price: order
price
aOrderId: num­
ber that identifi­
cates the Order.
ModifyTriggerOrder_TrailingStop aSize: size of the  
order aTrailVal­
ue: trail value of
the order
aOrderId: num­
GetOrderStatus ber that identifi­  
cates the Order.

388
COMPONENTS

aOrderClientId:
GetOrderStatusByClientId string that identi­  
ficates the Order.
aOrderId: num­
CancelOrder ber that identifi­  
cates the Order.
aOrderClientId:
CancelOrderByClientId string that identi­  
ficates the Order.
aOrderId: num­
CancelOpenTriggerOrder ber that identifi­  
cates the Order.
CancelAllOrders    
 
Other
 
Method Arguments Description
aMarket: name of the
GetFills  
market
 
 
 

389
COMPONENTS

FTX | Connect WebSocket API


In order to connect to FTX WebSocket API, just create a new FTX API client and attach to TsgcWebSocketClient.
See below an example:

oClient := TsgcWebSocketClient.Create(nil);
oFTX := TsgcWSAPI_FTX.Create(nil);
oFTX.Client := oClient;
oClient.Active := True;

390
COMPONENTS

FTX | Subscribe WebSocket Channel


FTX offers a variety of channels where you can subscribe to get real-time updates of market data, orders...
Find below a sample of how subscribe to a Ticker:

oClient := TsgcWebSocketClient.Create(nil);
oFTX := TsgcWSAPI_FTX.Create(nil);
oFTX.Client := oClient;
oFTX.SubscribeTicker('BTC-PERP');

procedure OnFTXMessage(Sender: TObject; aType, aRawMessage: string);


begin
// here you will receive the ticker updates
end;

391
COMPONENTS

FTX | Get market Data


FTX offers public Market Data through REST Endpoints, when you call one of these endpoints, you will get an
snapshot of the market data requested.
The Market Data Endpoints doesn't require authentication, so are freely available to all users.
 
Example: to get an snapshot of the market BTC-PERP, do the following call

oFTX := TsgcWSAPI_FTX.Create(nil);
ShowMessage(oFTX.REST_API.GetMarket('BTC-PERP'));

392
COMPONENTS

FTX | Private REST API


The FTX REST API offer public and private endpoints. The Private endpoints requires that messages signed to in­
crease the security of transactions.
First you must login to your FTX account and create a new API, you will get the following values:
 
• ApiKey
• ApiSecret
 
These fields must be configured in the FTX property of the FTX API client component.
Once configured, you can start to do private requests to the FTX REST API
 

oFTX := TsgcWSAPI_FTX.Create(nil);
oFTX.FTX.ApiKey := '<your api key>';
oFTX.FTX.ApiSecret := '<your api secret>';
ShowMessage(oFTX.REST_API.GetAccount);

393
COMPONENTS

FTX | Place Orders


In order to place new orders in FTX, you require first your APIs to access your private data, check the following arti­
cle How Use Private REST API.
 
Once you have configured your API keys, you can start to place orders

Market Order

Place a new Market Order, buy 0.002 contracts of BTC-PERP

oFTX := TsgcWSAPI_FTX.Create(nil);
oFTX.FTX.ApiKey := 'your api key';
oFTX.FTX.ApiSecret := 'your api secret';
ShowMessage(oFTX.REST_API.PlaceMarketOrder('BTC-PERP', ftosBuy, 0.002));

Limit Order

Place a new Limit Order, buy 0.002 contracts of BTC-PERP at price limit of 10000

oFTX := TsgcWSAPI_FTX.Create(nil);
oFTX.FTX.ApiKey := 'your api key';
oFTX.FTX.ApiSecret := 'your api secret';
ShowMessage(oFTX.REST_API.PlaceLimitOrder('BTC-PERP', ftosBuy, 0.002, 10000));

394
COMPONENTS

API Pusher
Pusher
 
Pusher it's an easy and reliable platform with nice features based on WebSocket protocol: flexible pub/sub messag­
ing, live user lists (presence), authentication...
 
Pusher WebSocket API is 7.
 
Data is sent bi-directionally over a WebSocket as text data containing UTF8 encoded JSON (Binary WebSocket
frames are not supported).
 
You can call Ping method to test connection to the server. Essentially any messages received from the other party
are considered to mean that the connection is alive. In the absence of any messages, either party may check that
the other side is responding by sending a ping message, to which the other party should respond with a pong.
 
Before you connect, you must complete the following fields:
 

Pusher.Cluster := 'eu'; // cluster where is located your pusher account


Pusher.Key := '9c3b7ef25qe97a00116c'; // your pusher api key
Pusher.Name := 'js'; // optional, name of your application
Pusher.Version := '4.1';  // optional, version of your application
Pusher.TLS := True; // if encrypted, set to True
Pusher.Secret := '2dc792e1916ac49e6b3f'; // pusher secret string (needed for privateand absence channels)

 
Important
Pusher requires that websocket client connects to a URL using previous fields (key, cluster...), these fields are used
to build the url and this is done when you assign the client in pusher component. So, to be sure that URL is built
correctly, set the client after you have fill the pusher configuration fields. Find below pseudo-code:
 
// configure pusher fields
pusher.cluster = ...
pusher.key = ...
// set client
pusher.client = websocket client
// start connection
websocket client.Active = true;
 
 
After a successful connection, OnPusherConnect event is raised and you get following fields:
 
• Socket ID: A unique identifier for the connected client.
• Timeout: The number of seconds of server inactivity after which the client should initiate a ping message
(this is handled automatically by component).
 
In case of error, OnPusherError will be raised, and information about error provided. An error may be sent from
Pusher in response to invalid authentication, an invalid command, etc.
 
4000-4099
 
Indicates an error resulting in the connection being closed by Pusher, and that attempting to reconnect using
the same parameters will not succeed.
 
4000: Application only accepts SSL connections, reconnect using wss://
4001: Application does not exist
4003: Application disabled
4004: Application is over connection quota
4005: Path not found
4006: Invalid version string format
4007: Unsupported protocol version

395
COMPONENTS

4008: No protocol version supplied


 
4100-4199
 
Indicates an error resulting in the connection being closed by Pusher, and that the client may reconnect after
1s or more.
 
4100: Over capacity
 
4200-4299
 
Indicates an error resulting in the connection being closed by Pusher, and that the client may reconnect im­
mediately.
 
4200: Generic reconnect immediately
4201: Pong reply not received: ping was sent to the client, but no reply was received - see ping and
pong messages
4202: Closed after inactivity: The client has been inactive for a long time (currently 24 hours) and
client does not support ping. Please upgrade to a newer WebSocket draft or implement version 5 or
above of this protocol.
 
4300-4399
 
Any other type of error.
 
4301: Client event rejected due to rate limit
 

Channels
Channels are a fundamental concept in Pusher. Each application has a number of channels, and each client can
choose which channels it subscribes to.
 
Channels provide:
 
• A way of filtering data. For example, in a chat application, there may be a channel for people who want to
discuss ‘dogs’
• A way of controlling access to different streams of information. For example, a project management applica­
tion would want to authorise people to get updates about ‘projectX’
 
It's strongly recommended that channels are used to filter your data and that it is not achieved using events. This is
because all events published to a channel are sent to all subscribers, regardless of their event binding.
 
Channels don’t  need to be explicitly created and are instantiated on client demand. This means that creating a
channel is easy. Just tell a client to subscribe to it.
 
There are 3 types of channels:
 
• Public channels can be subscribed to by anyone who knows their name
• Private channels introduce a mechanism which lets your server control access to the data you are broad­
casting
• Presence channels are an extension of private channels. They let you ‘register’  user information on sub­
scription, and let other members of the channel know who’s online
 

Public Channels

Public channels should be used for publicly accessible data as they do not require any form authorisation in order
to be subscribed to.
 
You can subscribe and unsubscribe from channels at any time. There’s no need to wait for the Pusher to finish con­
necting first.
 
Example: subscribe to channel "my-channel".

396
COMPONENTS

Delphi
APIPusher.Subscribe('my-channel');

 
If you are subscribed successfully OnPusherSubscribe event will be raised, if there is an error you will get a mes­
sage in OnPusherError event.
 
All messages from the subscribed channel will be received OnPusherEvent event.
 
When Publish method is called and the channel is Public, the component instead of use the WebSocket protocol,
uses the HTTP protocol and calls the method TriggerEvent (publishi is not allowed using websocket protocol).

Private Channels

Requires Indy 10.5.7 or later


 
Private channels should be used when access to the channel needs to be restricted in some way. In order for a
user to subscribe to a private channel permission must be authorised.
 
Example: subscribe to channel "my-private-channel".
 

Delphi
APIPusher.Subscribe('my-private-channel', pscPrivateChannel);

 
If you are subscribed successfully OnPusherSubscribe event will be raised, if there is an error you will get a mes­
sage in OnPusherError event.
 
All messages from the subscribed channel will be received OnPusherEvent event.
 

Presence Channels

Requires Indy 10.5.7 or later


 
Presence channels build on the security of Private channels and expose the additional feature of an awareness of
who is subscribed to that channel. This makes it extremely easy to build chat room and “who’s online” type func­
tionality to your application. Think chat rooms, collaborators on a document, people viewing the same web page,
competitors in a game, that kind of thing.
 
Presence channels are subscribed to from the client API in the same way as private channels but the channel
name must be prefixed with presence-. As with private channels an HTTP Request is made to a configurable au­
thentication URL to determine if the current user has permissions to access the channel.
 
Information on users subscribing to, and unsubscribing from a channel can then be accessed by binding to events
on the presence channel and the current state of users subscribed to the channel is available via the
channel.members property.
 
Example: subscribe to channel "my-presence-channel".
 

APIPusher.Subscribe('my-presence-channel', pscPresenceChannel,
  '{"user_id":"John_Smith","user_info":{"name":"John Smith"}}')

 
If you are subscribed successfully OnPusherSubscribe event will be raised, if there is an error you will get a mes­
sage in OnPusherError event.
 

397
COMPONENTS

All messages from the subscribed channel will be received OnPusherEvent event.
 
 
 

Publish Messages
Not only you can receive messages from subscribed channels, but you can also send messages to other sub­
scribed users.
Call method Publish to send a message to all subscribed users of channel.
 
Example: send an event to all subscribed users of "my-channel'
 

APIPusher.Publish('my-event', 'my-channel');

 
Publish no more than 10 messages per second per client (connection). Any events triggered above this rate limit
will be rejected by Pusher API. This is not a system issue, it is a client issue. 100 clients in a channel sending mes­
sages at this rate would each also have to be processing 1,000 messages per second! Whilst some modern
browsers might be able to handle this it’s most probably not a good idea.
 

REST API
The API is hosted at http://api-CLUSTER.pusher.com , where CLUSTER is replaced with your own apps cluster (for
instance, eu).
 
HTTP status codes are used to indicate the success or otherwise of requests. The following status are common:
 
200 Successful request. Body will contain a JSON hash of response data
400 Error: details in response body
401 Authentication error: response body will contain an explanation
403 Forbidden: app disabled or over message quota
 
The following REST API functions have been implemented.
 
Function Description
triggers a new event on the specified
TriggerEvent
channel.
GetChannels provide a list of all channels active.
GetChannel provide information of a channel.
provide a list of all users connected to
GetUsers
a channel.
 
 

Custom Authentication
Pusher only allow subscribe to private or presence channels, if the connection provides an authentication token,
this allows to restrict the access.
You can build your own Authentication flow, using OnPusherAuthentication event, this event is called before the
subscription message is signed with the secret key provided by Pusher. This event has 2 parameters a request au­
thentication with fields like SocketId, channel name... which can be used by your own authentication server to au­
thenticate or not the request. Find below a screenshot which shows the pusher authentication flow
 

398
COMPONENTS

 
When a client connects to the pusher server, it sends the Key provided by pusher and the server returns an identifi­
cation id (socket_id).
 
When a client subscribes to a private (or presence) channel, the sgcWebSockets client uses the Secret Key provid­
ed by pusher to create a signature which is included in the subscription message. Using the OnPusherAutentication
event, you can capture the fields required to sign the message, implement your own authentication methods and if
successful, return the signature and this signature will be included in the subscription message and sent to the
server.
 
Example:

oClient := TsgcWebSocketClient.Create(nil);
oPusher := TsgcWSAPI_Pusher.Create(nil);
oPusher.Client := oClient;
oPusher.Cluster := 'eu';
Pusher.Name := 'js';
Pusher.Version := '4.1';
Pusher.TLS := True;
Pusher.Key := '9c3b7ef25qe97a00116c';
Pusher.Secret := ''; // the secret key is not known by the client, only by the authentication module
 
oPusher.OnPusherAuthentication := OnPusherAuthenticationEvent;

399
COMPONENTS

 
procedure OnPusherAuthenticationEvent(Sender: TObject; AuthRequest: TsgcWSPusherRequestAuthentication;
  AuthResponse: TsgcWSPusherResponseAuthentication);
begin
  // if the authentication request is succesful return the signature
  if CustomAuthentication(AuthRequest.Channel, AuthRequest.SocketID) then
    AuthResponse.Signature := GetCustomAuthenticationSignature;
end;

The format of the signature is:


 
Private channels: key:HMAC256(SocketID, ChannelName)
Presence channels: key: HMAC256(SocketID, ChannelName, Data)

400
COMPONENTS

API Bittrex
Bittrex
 
The Bittrex WebSocket API is implemented using SignalR. Latest supported API is V3.
 
Bittrex component has a property called Bittrex where you can fill API Keys provided by Bittrex to get access to
your account data.
 
 

Authentication
In order to subscribe to private methods, first you must authenticate against Bittrex servers. Then Authentication re­
quires first set your API Key and Secret in client component (this values can be obtained from your Bittrex ac­
count).
Once you have filled the API Keys, call the method Authenticate, if successful, then OnBittrexAuthenticate event
will be called.
 
You can check at any time, if you are authenticated. Call the method IsAuthenticate and you will get a true/false
response, this method awaits till server sends a response or time out has expired.
 
After authenticating, the client renews automatically the authentication, there is no need to manually authenticate
because the component it does automatically when receives a message that authentication is going to expire.
 

Private Methods

Method Parameters Description


Sends a message
when the authenticat­
SubscribeBal­
  ed user’s total or avail­
ance
able balance of a cur­
rency changes.
Sends a message
SubscribeDe­ when a new deposit is
 
posit detected or its status
changes.
Sends messages
Sub­ when there are
 
scribeOrder changes to the user’s 
open orders.
 

Public Methods

Method Parameters Description


Sends a message at
the start of each can­
SubscribeCan­ Symbol, In­ dle (based on the sub­
dle terval scribed interval) and
when trades have oc­
curred on the market.

401
COMPONENTS

Sends an empty mes­
sage on an interval
(currently 5 seconds).
If you stop getting a
heartbeat that means
your connection is
Sub­
dead. If you are still
scribeHeart­  
getting a heartbeat but
Beat
are not getting updates
on active markets then
that means your con­
nection is alive but
something else is
wrong.
Provides regular up­
dates of the current
market summary data
for all markets. Market
summary data is differ­
SubscribeMar­
  ent from candles in
ketSummaries
that it is a rolling 24-
hour number as op­
posed to data for a
fixed interval like can­
dles.
Provides regular up­
dates of the current
market summary data
for a given market.
Market summary data
SubscribeMar­
Symbol is different from can­
ketSummary
dles in that it is a
rolling 24-hour number
as opposed to data for
a fixed interval like
candles.
Sends a message
Sub­ when there are
Symbol,
scribeOrder­ changes to the order
Depth
Book book within the sub­
scribed depth.
Sends a message with
the best bid price, best
ask price, and last
SubscribeTick­
  trade price for all mar­
ers
kets as there are
changes to the order
book or trades.
Sends a message with
the best bid and ask
SubscribeTick­ price for the given mar­
Symbol
er ket as well as the last
trade price whenever
there is a relevant

402
COMPONENTS

change to the order


book or a trade.
Sends a message with
Subscribe­ the quantity and rate of
Symbol
Trade trades on a market as
they occur.
 
 

Events

Event Parameters Description


When client is suc­
OnBittrexAu­
  cessfully authenticated
thenticated
(or re-authenticated).
OnBittrexCon­ When client connects
 
nect to Bittrex servers.
When client discon­
OnBittrexDis­
  nects from Bittrex
connect
servers.
When there is any er­
OnBittrexErrror  
ror in Bittrex protocol.
OnBittrex­ When receives a
 
HeartBeat heartbeat from server.
When receives an up­
OnBittrexMes­
  date from any channel
sage
subscribed.
OnBittrexSub­ When client subscribes
 
scribed to a channel.
When client unsub­
OnBittrexUn­
  scribes from a chan­
Subscribed
nel.
 

403
COMPONENTS

API Bitmex
Bitmex
 
Is a cryptocurrency exchange and derivative trading platform.
 
The following APIs are supported:
 
1. WebSocket streams: allows to subscribe to some methods and get data in real-time. Events are pushed to
clients by server to subscribers. Uses WebSocket as protocol.
2. REST API: clients can request to server market and account data. Requires an API Key and Secret to au­
thenticate and uses HTTPs as protocol.
 

Properties
Bitmex API has 2 types of methods: public and private. Public methods can be accessed without authentication, ex­
ample: get ticker prices. Only are only private and related to user data, those methods requires the use of Bitmex
API keys.
 
• ApiKey: you can request a new api key in your Bitmex account, just copy the value to this property.
• ApiSecret: it's the secret of the API, keep safe.
• TestNet: if enabled it will connect to Bitmex Demo Account (by default false).
• HTTPLogOptions: stores in a text file a log of HTTP requests
• Enabled: if enabled, will store all HTTP requests of WebSocket API.
• FileName: full path of filename where logs will be stored
 
 

Most common uses


• WebSockets API
• How Connect WebSocket API
• How Subscribe WebSocket Channel
• REST API
• How Place Bitmex Order
 

WebSocket API
 
  Subscribe / Unsubscribe
    
BitMEX allows subscribing to real-time data. This access is not rate-limited once connected and is the best
way to get the most up-to-date data to your programs. In some topics, you can pass a Symbol to filter events
by symbol, example: trades, quotes...
 
The following subscription topics are available without authentication:
 
• btmAnnouncement: Site Announcements
• btmChat: Trollbox chat
• btmConnected: Statistics of connected users/bots
• btmFunding: Updates of swap funding rates. Sent every funding interval (usually 8hrs)
• btmInstrument: Instrument updates including turnover and bid/ask
• btmInsurance: Daily Insurance Fund updates
• btmLiquidation: Liquidation orders as they're entered into the book
• btmOrderBookL2_25: Top 25 levels of level 2 order book
• btmOrderBookL2: Full level 2 order book
• btmOrderBook10: Top 10 levels using traditional full book push

404
COMPONENTS

• btmPublicNotifications: System-wide notifications (used for short-lived messages)


• btmQuote: Top level of the book
• btmQuoteBin1m: 1-minute quote bins
• btmQuoteBin5m: 5-minute quote bins
• btmQuoteBin1h: 1-hour quote bins
• btmQuoteBin1d: 1-day quote bins
• btmSettlement: Settlements
• btmTrade: Live trades
• btmTradeBin1m: 1-minute trade bins
• btmTradeBin5m: 5-minute trade bins
• btmTradeBin1h:1-hour trade bins
• btmTradeBin1d: 1-day trade bins
 
The following subjects require authentication:
 
• btmAffiliate: Affiliate status, such as total referred users & payout %
• btmExecution: Individual executions; can be multiple per order
• btmOrder: Live updates on your orders
• btmMargin: Updates on your current account balance and margin requirements
• btmPosition: Updates on your positions
• btmPrivateNotifications: Individual notifications - currently not used
• btmTransact: Deposit/Withdrawal updates
• btmWallet: Bitcoin address balance data, including total deposits & withdrawals
 
 
Example of messages received:
 

{
      "table":"orderBookL2_25",
      "keys":["symbol","id","side"],
      "types":{"id":"long","price":"float","side":"symbol","size":"long","symbol":"symbol"}
      "foreignKeys":{"side":"side","symbol":"instrument"},
      "attributes":{"id":"sorted","symbol":"grouped"},
      "action":"partial",
      "data":[
        {"symbol":"XBTUSD","id":17999992000,"side":"Sell","size":100,"price":80},
        {"symbol":"XBTUSD","id":17999993000,"side":"Sell","size":20,"price":70},
        {"symbol":"XBTUSD","id":17999994000,"side":"Sell","size":10,"price":60},
        {"symbol":"XBTUSD","id":17999995000,"side":"Buy","size":10,"price":50},
        {"symbol":"XBTUSD","id":17999996000,"side":"Buy","size":20,"price":40},
        {"symbol":"XBTUSD","id":17999997000,"side":"Buy","size":100,"price":30}
      ]
}
 
{
      "table":"orderBookL2_25",
      "action":"update",
      "data":[
        {"symbol":"XBTUSD","id":17999995000,"side":"Buy","size":5}
      ]
    }
{
      "table":"orderBookL2_25",
      "action":"delete",
      "data":[
        {"symbol":"XBTUSD","id":17999995000,"side":"Buy"}
      ]
}
{
      "table":"orderBookL2_25",
      "action":"insert",
      "data":[
        {"symbol":"XBTUSD","id":17999995500,"side":"Buy","size":10,"price":45},
      ]
}

Authentication
    
If you wish to subscribe to user-locked streams, you must authenticate first. Note that invalid authentication
will close the connection.
 
BitMEX API usage requires an API Key.
 

405
COMPONENTS

Permanent API Keys can be locked to IP address ranges and revoked at will without compromising your
main credentials. They also do not require renewal.
 
To use API Key auth, you must generate an API Key in your account.
 
Cal method Authenticate before subscribe to any Authenticated Topic.

REST API
 
Method Description
This returns all raw transactions, which includes order opening and cancela­
GetExecutions
tion, and order status changes.
GetExecutionsTrade­
This returns more focused Transactions.
History
This returns all instruments and indices, including those that have settled or are
GetInstruments unlisted. Use this endpoint if you want to query for individual instruments or use
a complex filter.
GetOrders To get open orders only
PlaceOrder Place a raw order using TsgcHTTPBitmexOrder object.
PlaceMarketOrder Place a new MARKET order.
PlaceLimitOrder Place a new LIMIT order.
PlaceStopOrder Place a new STOP order.
PlaceStopLimitOrder Place a new STOPLIMIT order.
AmendOrder Modify an existing order.
CancelOrder Cancels an active Order.
CancelAllOrders Cancel All Active Orders.
CancelAllOrdersAfter Cancel All Orders after some time.
ClosePosition Close an open position.
GetOrderBook Get Current OrderBook in vertifcal format
GetPosition Get your positions.
SetPositionIsolate Enable isolated margin or cross-margin per position.
SetPositionLeverage Choose leverage per position.
SetPositionRiskLimit Update your risk limit.
SetPositionTransfer­
Transfer equity in or out of a position.
Margin
GetQuotes Get Quotes
GetTrades Get Trades
 
 

406
COMPONENTS

Bitmex | Connect WebSocket API


In order to connect to Bitmex WebSocket API, just create a new Binance API client and attach to TsgcWebSocket­
Client.
See below an example:

oClient := TsgcWebSocketClient.Create(nil);
oBitmex := TsgcWSAPI_Bitmex.Create(nil);
oBitmex .Client := oClient;
oClient.Active := True;

407
COMPONENTS

Bitmex | Subscribe WebSocket Channel
Bitmex offers a variety of channels where you can subscribe to get real-time updates of market data, orders... Find
below a sample of how subscribe to a Trade Channel:

oClient := TsgcWebSocketClient.Create(nil);
oBitmex := TsgcWSAPI_Bitmex.Create(nil);
oBitmex.Client := oClient;
oBitmex.Subscribe(btmTrade, 'XBTUSD');
procedure OnBitmexMessage(Sender: TObject; const aTopic: TwsBitmexTopics; const aMessage: string);
begin
// here you will receive the trade updates
end;

408
COMPONENTS

Bitmex | How Place Orders


The Bitmex REST API offer public and private endpoints. The Private endpoints requires that messages signed to
increase the security of transactions.
First you must login to your Bitmex account and create a new API, you will get the following values:
 
• ApiKey
• ApiSecret
 
These fields must be configured in the Bitmex property of the Bitmex API client component. Once configured, you
can start to do private requests to the Bitmex REST API.
 

Order Types

All orders require a symbol. All other fields are optional except when otherwise specified.
These are the valid ordTypes:
 
• Limit: The default order type. Specify an orderQty and price.
• Market: A traditional Market order. A Market order will execute until filled or your bankruptcy price is reached,
at which point it will cancel.
• Stop: A Stop Market order. Specify an orderQty and stopPx. When the stopPx is reached, the order will be 
entered into the book.
◦ On sell orders, the order will trigger if the triggering price is lower than the stopPx. On buys, higher.
◦ Note: Stop orders do not consume margin until triggered. Be sure that the required margin is available
in your account so that it may trigger fully.
◦ Close Stops don't require an orderQty. See Execution Instructions below.
• StopLimit: Like a Stop Market, but enters a Limit order instead of a Market order. Specify
an orderQty, stopPx, and price.
• MarketIfTouched: Similar to a Stop, but triggers are done in the opposite direction. Useful for Take Profit or­
ders.
• LimitIfTouched: As above; use for Take Profit Limit orders.
• Pegged: Pegged orders allow users to submit a limit price relative to the current market price. Specify
a pegPriceType, and pegOffsetValue.
◦ Pegged orders must have an execInst of Fixed. This means the limit price is set at the time the order 
is accepted and does not change as the reference price changes.
◦ PrimaryPeg: Price is set relative to near touch price.
◦ MarketPeg: Price is set relative to far touch price.
◦ A pegPriceType submitted with no ordType is treated as a Pegged order.

Execution Instructions

The following execInsts are supported. If using multiple, separate with a comma (e.g. LastPrice,Close).


 
• ParticipateDoNotInitiate: Also known as a Post­Only order. If this order would have executed on place­
ment, it will cancel instead. This is intended to protect you from the far touch moving towards you while the
order is in transit. It is not intended for speculating on the far touch moving away after submission ­ we con­
sider such behaviour abusive and monitor for it.
• MarkPrice, LastPrice, IndexPrice: Used by stop and if-touched orders to determine the triggering price.
Use only one. By default, MarkPrice is used. Also used for Pegged orders to define the value of LastPeg.
• ReduceOnly: A ReduceOnly order can only reduce your position, not increase it. If you have 
a ReduceOnly limit order that rests in the order book while the position is reduced by other orders, then its 
order quantity will be amended down or canceled. If there are multiple ReduceOnly orders the least aggres­
sive will be amended first.
• Close: Close implies ReduceOnly. A Close order will cancel other active limit orders with the same side and 
symbol if the open quantity exceeds the current position. This is useful for stops: by canceling these orders,
a Close Stop is ensured to have the margin required to execute, and can only execute up to the full size of 
your position. If orderQty is not specified, a Close order has an orderQty equal to your current position's size.

409
COMPONENTS

◦ Note that a Close order without an orderQty requires a side, so that BitMEX knows if it should trigger 
above or below the stopPx.
• LastWithinMark: Used by stop orders with LastPrice to allow stop triggers only when:
◦ For Sell Stop Market / Stop Limit Order
▪ Last Price <= Stop Price
▪ Last Price >= Mark Price × (1 - 5%)
◦ For Buy Stop Market / Stop Limit Order:
▪ Last Price >= Stop Price
▪ Last Price <= Mark Price × (1 + 5%)
• Fixed: Pegged orders must have an execInst of Fixed. This means the limit price is set at the time the order 
is accepted and does not change as the reference price changes.

Pegged Orders

Pegged orders allow users to submit a limit price relative to the current market price. The limit price is set once
when the order is submitted and does not change with the reference price. This order type is not intended for spec­
ulating on the far touch moving away after submission - we consider such behaviour abusive and monitor for it.
 
Pegged orders have an ordType of Pegged, and an execInst of Fixed.
 
A pegPriceType and pegOffsetValue must also be submitted:
• PrimaryPeg ­ price is set relative to the near touch price
• MarketPeg ­ price is set relative to the far touch price

Trailing Stop Pegged Orders

Use pegPriceType of TrailingStopPeg to create Trailing Stops.


 
The price is set at submission and updates once per second if the underlying price (last/mark/index) has moved by
more than 0.1%. stopPx then moves as the market moves away from the peg, and freezes as the market moves to­
ward it.
 
Use pegOffsetValue to  set the stopPx of  your order. The peg is set to the triggering price specified in
the execInst (default MarkPrice). Use a negative offset for stop-sell and buy-if-touched orders.
 
Requires ordType: Stop, StopLimit, MarketIfTouched, LimitIfTouched.

Trailing Stops

You may use pegPriceType of 'TrailingStopPeg' to create Trailing Stops. The pegged stopPx will move as the mar­


ket moves away from the peg, and freeze as the market moves toward it.
 
To use, combine with pegOffsetValue to set the stopPx of your order. The peg is set to the triggering price specified
in the execInst (default 'MarkPrice'). Use a negative offset for stop-sell and buy-if-touched orders.
 
Requires ordType: 'Stop', 'StopLimit', 'MarketIfTouched', 'LimitIfTouched'.

Tracking Your Orders

If you want to keep track of order IDs yourself, set a unique clOrdID per  order. This clOrdID will  come back as a
property on the order and any related executions (including on the WebSocket), and can be used to get or cancel
the order. Max length is 36 characters.
 
Examples:

// buy market order


BITMEX.REST_API.PlaceMarketOrder(bmosBuy, 'XBTUSD', 100);
// sell limit order at 45000
BITMEX.REST_API.PlaceLimitOrder(bmosSell, 'XBTUSD', 100, 45000.00);
// stop order at 48000
BITMEX.REST_API.PlaceStopOrder(bmosSell, 'XBTUSD', 100, 48000.00);

410
COMPONENTS

API Bitfinex
Bitfinex
 
Bitfinex is one of the world's largest and most advanced cryptocurrency trading platform. Users can exchange Bit­
coin, Ethereum, Ripple, EOS, Bitcoin Cash, Iota, NEO, Litecoin, Ethereum Classic...
 
Bitfinex WebSocket API version is 2.0
 
Each message sent and received via the Bitfinex's WebSocket channel is encoded in JSON format
 
A symbol can be a trading pair or a margin currency:
 
• Trading pairs symbols are formed prepending a "t" before the pair (i.e tBTCUSD, tETHUSD).
• Margin currencies symbols are formed prepending an "f" before the currency (i.e fUSD, fBTC, ...)
 
 
After a successful connection, OnBitfinexConnect event is raised and you get Bitfinex API Version number as a
parameter.
 
You can call Ping method to test connection to the server.
 
If the server sends any information, this can be handle using OnBitfinexInfoMessage event, where a Code and a
Message are parameters with information about the message sent by the server. Example codes:
 
20051 : Stop/Restart WebSocket Server (please reconnect)
20060 : Entering in Maintenance mode. Please pause any activity and resume after receiving the info mes­
sage 20061 (it should take 120 seconds at most).
20061 : Maintenance ended. You can resume normal activity. It is advised to unsubscribe/subscribe again all
channels.
 
In case of error, OnBitfinexError will be raised, and information about error provided. Example error codes:
 
10000 : Unknown event
10001 : Unknown pair
 
In order to change the configuration, call Configuration method and pass as a parameter one of the following
flags:
 
CS_DEC_S = 8; // Enable all decimal as strings.
CS_TIME_S = 32; // Enable all times as date strings.
CS_SEQ_ALL = 65536; // Enable sequencing BETA FEATURE
CHECKSUM = 131072; // Enable checksum for every book iteration. Checks the top 25 entries for each side
of the book. The checksum is a signed int.
 

Subscribe Public Channels


There are channels which are public and there is no need to authenticate against the server. All messages are
raised OnBitfinexUpdate event.
 

SubscribeTicker

The ticker is a high level overview of the state of the market. It shows you the current best bid and ask, as well as
the last trade price. It also includes information such as daily volume and how much the price has moved over the
last day.
 

411
COMPONENTS

// Trading pairs
[
  CHANNEL_ID,
  [
    BID,
    BID_SIZE,
    ASK,
    ASK_SIZE,
    DAILY_CHANGE,
    DAILY_CHANGE_PERC,
    LAST_PRICE,
    VOLUME,
    HIGH,
    LOW
  ]
]
// Funding pairs
[
  CHANNEL_ID,
  [
    FRR,
    BID,
    BID_PERIOD,
    BID_SIZE,
    ASK,
    ASK_PERIOD,
    ASK_SIZE,
    DAILY_CHANGE,
    DAILY_CHANGE_PERC,
    LAST_PRICE,
    VOLUME,
    HIGH,
    LOW
  ]
]

 
 

SubscribeTrades
This channel sends a trade message whenever a trade occurs at Bitfinex. It includes all the pertinent details of the
trade, such as price, size and time.
 

// on trading pairs (ex. tBTCUSD)


[
  CHANNEL_ID,
  [
    [
      ID,
      MTS,
      AMOUNT,
      PRICE
    ],
    ...
  ]
]
// on funding currencies (ex. fUSD)
[
  CHANNEL_ID,
  [
    [
      ID,
      MTS,
      AMOUNT,
      RATE,
      PERIOD
    ],
    ...
  ]
]

412
COMPONENTS

SubscribeOrderBook
The Order Books channel allows you to keep track of the state of the Bitfinex order book. It is provided on a price
aggregated basis, with customizable precision. After receiving the response, you will receive a snapshot of the
book, followed by updates upon any changes to the book.
 

// on trading pairs (ex. tBTCUSD)


[
  CHANNEL_ID,
  [
    [
      PRICE,
      COUNT,
      AMOUNT
    ],
    ...
  ]
]
  
// on funding currencies (ex. fUSD)
[
  CHANNEL_ID,
  [
    [
      RATE,
      PERIOD,
      COUNT,
      AMOUNT
    ],
    ...
  ]
]

SubscribeRawOrderBook
These are the most granular books.
 

// on trading pairs (ex. tBTCUSD)


[
  CHANNEL_ID,
  [
    [
      ORDER_ID,
      PRICE,
      AMOUNT
    ],
    ...
  ]
]
  
// on funding currencies (ex. fUSD)
[
  CHANNEL_ID,
  [
    [
      OFFER_ID,
      PERIOD,
      RATE,
      AMOUNT
    ],
    ...
  ]
]

SubscribeCandles
Provides a way to access charting candle info. Time Frames:
 

413
COMPONENTS

1m: one minute


5m : five minutes
15m : 15 minutes
30m : 30 minutes
1h : one hour
3h : 3 hours
6h : 6 hours
12h : 12 hours
1D : one day
7D : one week
14D : two weeks
1M : one month
 

[
  CHANNEL_ID,
  [
    [
      MTS,
      OPEN,
      CLOSE,
      HIGH,
      LOW,
      VOLUME
    ],
    ...
  ]
]

 
 
 

Subscribe Authenticated Channels


This channel allows you to keep up to date with the status of your account. You can receive updates on your posi­
tions, your balances, your orders and your trades.
 
Use Authenticate method in order to Authenticate against the server and set required parameters.
 
Once authenticated, you will receive updates of: Orders, positions, trades, funding offers, funding credits, funding
loans, wallets, balance info, margin info, funding info, funding trades...
 
You can request UnAuthenticate method if you want to log off from the server.
 
 
 
 
 

414
COMPONENTS

API Discord
Discord
 
Gateways are Discord's form of real-time communication over secure WebSockets. Clients will receive events and
data over the gateway they are connected to and send data over the REST API.
 

Authorization
First you must generate a new Bot, and copy Bot Token which will be used to authenticate through API. Then set
this token in API Component.
 

Delphi
TsgcWSAPI_Discord.DiscordOptions.BotOptions.Token := '... bot token here ...';

Intents
Maintaining a stateful application can be difficult when it comes to the amount of data you're expected to process,
especially at scale. Gateway Intents are a system to help you lower that computational burden.
When identifying to the gateway, you can specify an intents parameter which allows you to conditionally subscribe
to pre-defined "intents", groups of events defined by Discord. If you do not specify a certain intent, you will not re­
ceive any of the gateway events that are batched into that group. The valid intents are (zero value means all events
are received):
 
GUILDS (1 << 0) = Integer (1)
  ­ GUILD_CREATE
  ­ GUILD_DELETE
  ­ GUILD_ROLE_CREATE
  ­ GUILD_ROLE_UPDATE
  ­ GUILD_ROLE_DELETE
  ­ CHANNEL_CREATE
  ­ CHANNEL_UPDATE
  ­ CHANNEL_DELETE
  ­ CHANNEL_PINS_UPDATE
GUILD_MEMBERS (1 << 1) = Integer (2)
  ­ GUILD_MEMBER_ADD
  ­ GUILD_MEMBER_UPDATE
  ­ GUILD_MEMBER_REMOVE
GUILD_BANS (1 << 2) = Integer (4)
  ­ GUILD_BAN_ADD
  ­ GUILD_BAN_REMOVE
GUILD_EMOJIS (1 << 3) = Integer (8)
  ­ GUILD_EMOJIS_UPDATE
GUILD_INTEGRATIONS (1 << 4) = Integer (16)
  ­ GUILD_INTEGRATIONS_UPDATE
GUILD_WEBHOOKS (1 << 5) = Integer (32)
  ­ WEBHOOKS_UPDATE
GUILD_INVITES (1 << 6) = Integer (64)
  ­ INVITE_CREATE
  ­ INVITE_DELETE
GUILD_VOICE_STATES (1 << 7) = Integer (128)
  ­ VOICE_STATE_UPDATE
GUILD_PRESENCES (1 << 8) = Integer (256)
  ­ PRESENCE_UPDATE
GUILD_MESSAGES (1 << 9) = Integer (512)

415
COMPONENTS

  ­ MESSAGE_CREATE
  ­ MESSAGE_UPDATE
  ­ MESSAGE_DELETE
GUILD_MESSAGE_REACTIONS (1 << 10) = Integer (1024)
  ­ MESSAGE_REACTION_ADD
  ­ MESSAGE_REACTION_REMOVE
  ­ MESSAGE_REACTION_REMOVE_ALL
  ­ MESSAGE_REACTION_REMOVE_EMOJI
GUILD_MESSAGE_TYPING (1 << 11) = Integer (2048)
  ­ TYPING_START
DIRECT_MESSAGES (1 << 12) = Integer (4096)
  ­ CHANNEL_CREATE
  ­ MESSAGE_CREATE
  ­ MESSAGE_UPDATE
  ­ MESSAGE_DELETE
  ­ CHANNEL_PINS_UPDATE
DIRECT_MESSAGE_REACTIONS (1 << 13) = Integer (8192)
  ­ MESSAGE_REACTION_ADD
  ­ MESSAGE_REACTION_REMOVE
  ­ MESSAGE_REACTION_REMOVE_ALL
  ­ MESSAGE_REACTION_REMOVE_EMOJI
DIRECT_MESSAGE_TYPING (1 << 14) = Integer (16384)
  ­ TYPING_START

HeartBeat
HeartBeats are automatically handle by component so you don't need to worry about it. When client connects to
server, server sends a HELLO response with heartbeat interval, component reads response and adjust automati­
cally heartbeat so send a ping every x seconds. Sometimes server can send a ping to client, this is handled auto­
matically by client too.
 

Connection Ready
When connection is ready, after a successful login and authorization by server, OnDiscordReady event is raised
and then you can start to receive updates from server.
 

Connection Resume
 
If connection closes unexpectedly, when client tries to reconnect, it calls OnDiscordBeforeReconnect event, com­
ponent automatically saves all data needed to make a successful resume, but parameters can be changed if need­
ed. If you don't want to reconnect and start a new clean session, just set Reconnect to False.
 
If session is resumed, OnDiscordResumed event is fired. If it's a new session, OnDiscordReady fill be fired.
 
 

Dispatch Events
Events are dispatched OnDiscordDispatch, so here you can read events sent by server to client.
 

Delphi
procedure OnDiscordDispatch(Sender: TObject; const aEvent, RawData: string);
begin
  DoLog('#discord dispatch: ' + aEvent + ' ' + RawData);
end;

416
COMPONENTS

  aEvent parameter contains parameter  name. RawData contains full JSON message.     HTTP Requests In or­


der to request info about guild, users, udpate data...  instead  of use gateway websocket messages, Discord re­
quires to use HTTP requests,    so find bellow all methods available to do an HTTP request:       function 
GET_Request(const aPath: String): string;     function POST_Request(const aPath, aMessage:  String): string;
    function PUT_Request(const aPath, aMessage:  String): string;     function PATCH_Request(const aPath, aMes­
sage:  String): string;     function DELETE_Request(const aPath: String):  string;   Example: get current user info

Delphi
result := GET_Request('/users/@me');

 
sample response from server:

{
"id": "637423922035480852",
"username": "test",
"avatar": null,
"discriminator": "5125",
"bot": true,
"email": null,
"verified": true,
"locale": "en-US",
"mfa_enabled": false,
"flags": 0
}

417
COMPONENTS

API Huobi
Huobi
 
Huobi is an international multi-language cryptocurrency exchange.
 

Methods
 
  SubscribeKLine
 
    K line data, including the opening price, closing price, highest price, lowest price, volume, turnover, number of
transactions, etc. per unit time interval $period Optional values: { 1min, 5min, 15min, 30min, 60min, 4hour ,1day,
1mon, 1week, 1year }
 
{

{
  "status": "ok",
  "rep": "market.btcusdt.kline.1min",
  "tick": [
    {
      "amount": 1.6206,
      "count":  3,
      "id":     1494465840,
      "open":   9887.00,
      "close":  9885.00,
      "low":    9885.00,
      "high":   9887.00,
      "vol":    16021.632026
    },
    {
      "amount": 2.2124,
      "count":  6,
      "id":     1494465900,
      "open":   9885.00,
      "close":  9880.00,
      "low":    9880.00,
      "high":   9885.00,
      "vol":    21859.023500
    }
  ]
}

 
 
  SubscribeMarketDepth
 
    Handbook depth, according to different step aggregation, buy one, buy two, buy three, and sell one, sell two, sell
three, etc. type Optional value: { step0, step1, step2, step3, step4, step5, percent10 } (combination depth 0-5);
when step0, no depth is merged
 

{
  "ch": "market.btcusdt.depth.step0",
  "ts": 1489474082831,
  "tick": {
    "bids": [
    [9999.3900,0.0098], // [price, amount]
    [9992.5947,0.0560],
    // more Market Depth data here
    ]
    "asks": [
    [10010.9800,0.0099]
    [10011.3900,2.0000]
    //more data here
    ]

418
COMPONENTS

  }
}

 
 
  SubscribeTradeDetail
 
    Transaction record, including transaction price, volume, direction of transaction, etc.
 

{
  "ch": "market.btcusdt.trade.detail",
  "ts": 1489474082831,
  "tick": {
        "id": 14650745135,
        "ts": 1533265950234,
        "data": [
            {
                "amount": 0.0099,
                "ts": 1533265950234,
                "id": 146507451359183894799,
                "price": 401.74,
                "direction": "buy"
            },
            // more Trade Detail data here
        ]
    }
  
  ]
  }
}

 
 
  SubscribeMarketDetail
 
    Last 24 hours of volume, turnover, opening price, closing price, highest price, lowest price, number of transac­
tions, etc.
 

{
  "rep": "market.btcusdt.detail",
  "status": "ok",
  "id": "id12",
  "tick": {
    "amount": 12224.2922,
    "open":   9790.52,
    "close":  10195.00,
    "high":   10300.00,
    "ts":     1494496390000,
    "id":     1494496390,
    "count":  15195,
    "low":    9657.00,
    "vol":    121906001.754751
  }
}

 
 
  SubscribeMarketTickers
 
    Information on the daily K line, the last 24 hours of trading, etc.
 
 

Events
  OnHuobiSubscribed: event called after a successful subscription.
 
  OnHuobiUnSubscribed: event called after a successful unsubscription.
 
  OnHuobiUpdate: every time there is an update in data (kline, market depth...) this event is called.

419
COMPONENTS

 
  OnHuobiError: if there is an error in Huobi API, this event will provide information about error.
 
 

420
COMPONENTS

API Cex
Cex
 
WebSocket API allows getting real-time notifications without sending extra requests, making it a faster way to ob­
tain data from the exchange
Cex component has a property called Cex where you can fill API Keys provided by Cex to get access to your ac­
count data.
 

Message encoding
• All messages are encoded in JSON format.
• Prices are presented as strings to avoid rounding errors at JSON parsing on client side
• Compression of WebSocket frames is not supported by the server.
• Time is presented as integer UNIX timestamp in seconds.
 

Authentication
To get access to CEX.IO WebSocket data, you should be authorized.
 
• Log in to CEX.IO account.
• Go to https://cex.io/trade/profile#/api page.
• Select the type of required permissions.
• Click "Generate Key" button and save your secret key, as it will become inaccessible after activation.
• Activate your key.
 

Connectivity
 
• If a connected Socket is inactive for 15 seconds, CEX.IO server will send a PING message.
• Only server can be an Initiator of PING request.
• The server sends ping only to the authenticated user.
• The user has to respond with a PONG message. Otherwise, the WebSocket will be DISCONNECTED. This
is handled automatically by the library.
• For the authenticated user, in case there is no notification or ping from the server within 15 seconds, it would
be safer to send a request like 'ticker' or 'get­balance' and receive a response, in order to ensure connectivi­
ty and authentication.
 
 

Public Channels
These channels don't require to Authenticate before. Responses from the server are received by OnCexMessage
event.
 
• SubscribeTickers: Ticker feed with only price of transaction made on all pairs (deprecated)
 

{
    "e": "tick",
    "data": {
        "symbol1": "BTC",
        "symbol2": "USD",
        "price": "428.0123"
    }
}

421
COMPONENTS

 
• SubscribeChart: OHLCV chart feeds with Open, High, Low, Close, Volume numbers (deprecated)
 

{
    'e': 'ohlcv24',
    'pair': 'BTC:USD',
    'data': [
        '418.2936',
        '420.277',
        '412.09',
        '416.9778',
        '201451078368'
    ]
}

 
• Subscribe Pair: Market Depth feed (deprecated)
 

{
    'e': 'md_groupped',
    'data': {
        'pair': 'BTC:USD',
        'id': 11296131,
        'sell': {
            '427.5000': 1000000,
            '480.0000': 263544334,
            ...
        },
        'buy': {
            '385.0000': 3630000,
            '390.0000': 1452458642,
            ... 400+ pairs togather with 'sell' pairs
        }
    }
}

 
• Subscribe Pair: Order Book feed (deprecated)
 

{
    'e': 'md',
    'data': {
        'pair': 'BTC:USD',
        'buy_total': 63221099,
        'sell_total': 112430315118,
        'id': 11296131,
        'sell': [
            [426.45, 10000000],
            [426.5, 66088429300],
            [427, 1000000],
            ... 50 pairs overaall
        ],
        'buy': [
            [423.3, 4130702],
            [423.2701, 10641168],
            [423.2671, 1000000],
            ... 50 pairs overaall
        ]
    }
}

Private Channels
To access these channels, first call Authenticate method. Responses from the server are received OnCexMessage
event.
 
GetTicker
 

422
COMPONENTS

{
    "e": "ticker",
    "data": {
        "timestamp": "1471427037",
        "low": "290",
        "high": "290",
        "last": "290",
        "volume": "0.02062068",
        "volume30d": "14.38062068",
        "bid": 240,
        "ask": 290,
        "pair": [
            "BTC",
            "USD"
        ]
    },
    "oid": "1471427036908_1_ticker",
    "ok": "ok"
}

 
GetBalance
 

{
    "e": "get-balance",
    "data": {
           "balance": {
            'LTC': '10.00000000',
            'USD': '1024.00',
            'RUB': '35087.98',
            'EUR': '217.53',
            'GHS': '10.00000000',
            'BTC': '9.00000000'
        },
           "obalance": {
              'BTC': '0.12000000',
              'USD': "512.00",
           },
       },
       "time": 1435927928597
    "oid": "1435927928274_2_get-balance",
    "ok": "ok"
}

 
SubscribeOrderBook
 

{
"e": "order-book-subscibe",
"data": {
   "timestamp": 1435927929,
   "bids": [
      [
         241.947,
         155.91626
      ],
      [
         241,
         981.1255
      ],
   ],
   "asks": [
      [
         241.95,
         15.4613
      ],
      [
         241.99,
         17.3303
      ],
   ],
   "pair": "BTC:USD",
   "id": 67809
},
"oid": "1435927928274_5_order-book-subscribe",
"ok": "ok"
}

423
COMPONENTS

 
UnSubscribeOrderBook
 

{
"e": "order-book-unsubscribe",
"data": {
   "pair": "BTC:USD"
},
"oid": "1435927928274_4_order-book-unsubscribe",
"ok": "ok"
}

 
 
GetOpenOrders
 

{
"e": "open-orders",
"data": [
   {
      "id": "2477098",
      "time": "1435927928618",
      "type": "buy",
      "price": "241.9477",
      "amount": "0.02000000",
      "pending": "0.02000000"
   },
   {
      "id": "2477101",
      "time": "1435927928634",
      "type": "sell",
      "price": "241.9493",
      "amount": "0.02000000",
      "pending": "0.02000000"
   }
],
"oid": "1435927928274_9_open-orders",
"ok": "ok"
}

 
 
PlaceOrder
 

{
"e": "place-order",
"data": {
   "complete": false,
   "id": "2477098",
   "time": 1435927928618,
   "pending": "0.02000000",
   "amount": "0.02000000",
   "type": "buy",
   "price": "241.9477"
},
"oid": "1435927928274_7_place-order",
"ok": "ok"
}

 
 
CancelReplaceOrder
 

{
"e": "cancel-replace-order",
"data": {
   "complete": false,
   "id": "2689009",
   "time": 1443464955904,
   "pending": "0.04000000",
   "amount": "0.04000000",

424
COMPONENTS

   "type": "buy",
   "price": "243.25"
},
"oid": "1443464955209_16_cancel-replace-order",
"ok": "ok"
}

 
GetOrderRequest
 
In CEX.IO system, orders can be present in the trade engine or in an archive database. There can be time periods
(~2 seconds or more), when the order is done/cancelled, but still not moved to the archive database. That means
you cannot see it using calls: archived-orders/open-orders. This call allows getting order information in any case.
Responses can have different format depending on orders location.
 

{
"e": "get-order",
"data": {
   "user": "XXX",
   "type": "buy",
   "symbol1": "BTC",
   "symbol2": "USD",
   "amount": "0.02000000",
   "remains": "0.02000000",
   "price": "50.75",
   "time": 1450214742160,
   "tradingFeeStrategy": "fixedFee",
   "tradingFeeBuy": "5",
   "tradingFeeSell": "5",
   "tradingFeeUserVolumeAmount": "nil",
   "a:USD:c": "1.08",
   "a:USD:s": "1.08",
   "a:USD:d": "0.00",
   "status": "a",
   "orderId": "5582060"
},
"oid": "1450214742135_10_get-order",
"ok": "ok"
}

 
CancelOrderRequest
 

{
"e": "cancel-order",
"data": {
   "order_id": "2477098"
   "time": 1443468122895
},
"oid": "1435927928274_12_cancel-order",
"ok": "ok"
}

 
GetArchivedOrders
 

{
"e": "archived-orders",
"data": [
   {
       "type": "buy",
       "symbol1": "BTC",
       "symbol2": "USD",
       "amount": 0,
       "amount2": 5000,
       "remains": 0,
       "time": "2015-04-17T10:46:27.971Z",
       "tradingFeeBuy": "2",
       "tradingFeeSell": "2",
       "ta:USD": "49.00",
       "fa:USD": "0.98",
       "orderId": "2340298",
       "status": "d",

425
COMPONENTS

       "a:BTC:cds": "0.18151851",
       "a:USD:cds": "50.00",
       "f:USD:cds": "0.98"
   },
   {
       "type": "buy",
       "symbol1": "BTC",
       "symbol2": "USD",
       "amount": 0,
       "amount2": 10000,
       "remains": 0,
       "time": "2015-04-08T15:46:04.651Z",
       "tradingFeeBuy": "2.99",
       "tradingFeeSell": "2.99",
       "ta:USD": "97.08",
       "fa:USD": "2.91",
       "orderId": "2265315",
       "status": "d",
       "a:BTC:cds": "0.39869578",
       "a:USD:cds": "100.00",
       "f:USD:cds": "2.91"
    }
],
"oid": "1435927928274    15_archived-orders",
"ok": "ok"
}

 
OpenPosition
 

{
    "e": "open-position",
    "oid": "1435927928274_7_open-position",
    "data": {   
        'amount': '1',
        'symbol': 'BTC',
        "pair": [
            "BTC",
            "USD"
        ],
        'leverage': '2',
        'ptype': 'long',
        'anySlippage': 'true',
        'eoprice': '650.3232',
        'stopLossPrice': '600.3232'
    }
}

 
GetPosition
 

{
  "e": "get_position",
  "ok": "ok",
  "data": {
    "user": "ud100036721",
    "pair": "BTC:USD",
    "amount": "1.00000000",
    "symbol": "BTC",
    "msymbol": "USD",
    "omamount": "1528.77",
    "lsymbol": "USD",
    "lamount": "3057.53",
    "slamount": "3380.11",
    "leverage": "3",
    "stopLossPrice": "3380.1031",
    "dfl": "3380.10310000",
    "flPrice": "3057.53333333",
    "otime": 1513002370342,
    "psymbol": "BTC",
    "ptype": "long",
    "ofee": "10",
    "pfee": "10",
    "cfee": "10",
    "tfeeAmount": "152.88",
    "rinterval": "14400000",
    "okind": "Manual",
    "a:BTC:c": "1.00000000",
    "a:BTC:s": "1.00000000",

426
COMPONENTS

    "oorder": "89101551",
    "pamount": "1.00000000",
    "lremains": "3057.53",
    "slremains": "3380.11",
    "oprice": "4586.3000",
    "status": "a",
    "id": "125531",
    "a:USD:cds": "4739.18"
  }
}

 
GetOpenPositions
 

{
    'e': 'open_positions',
    "oid": "1435927928256_7_open-positions",
    'ok': 'ok',
    'data': [
        {
            'user': 'ud100036721',
            'id': '104102',
            'otime': 1475602208467,
            'symbol': 'BTC',
            'amount': '1.00000000',
            'leverage': '2',
            'ptype': 'long',
            'psymbol': 'BTC',
            'msymbol': 'USD',
            'lsymbol': 'USD',
            'pair': 'BTC:USD',
            'oprice': '607.5000'
            'stopLossPrice': '520.3232',
            'ofee': '1',
            'pfee': '3',
            'cfee': '4',
            'tfeeAmount': '3.04',
            'pamount': '1.00000000',
            'omamount': '303.75',
            'lamount': '303.75',
            'oorder': '34106774',            
            'rinterval': '14400000',
            'dfl': '520.32320000',
            'slamount': '520.33',
            'slremains': '520.33',
            'lremains': '303.75',
            'flPrice': '303.75000000',
            'a:BTC:c': '1.00000000',
            'a:BTC:s': '1.00000000',
            'a:USD:cds': '610.54',
        },
        ...
    ]
}

 
ClosePosition
 

{   
    'e': 'close_position',
    "oid": "1435927928364_7_close-position",
    'ok': 'ok',
    'data': {
        'id': 104034,
        'ctime': 1475484981063,
        'ptype': 'long',
        'msymbol': 'USD'
        'pair': {
            'symbol1': 'BTC',
            'symbol2': 'USD'
        }
        'price': '607.1700',
        'profit': '-12.48',
    }
}

427
COMPONENTS

API FXCM
FXCM
 
FXCM, also known as Forex Capital Markets, is a retail broker for trading on the foreign exchange market. FXCM
allows people to speculate on the foreign exchange market and provides trading in contract for difference (CFDs)
on major indices and commodities such as gold and crude oil. It is based in London.
 
FXCM offers a web-based REST API which can be used to establish secure connectivity with FXCM’s trading sys­
tems for the purpose of receiving market data and trading.
 
FXCM sgcWebSockets component uses WebSocket (socket.io) and HTTP as transports to connect to a FXCM
Servers.
 

Connection
To use the REST API, you will need:
 
• Access Token generated with Trading Station Web https://tradingstation.fxcm.com/.
• Demo: if enabled, it will connect to FXCM Demo server (by default false).
 

// ... create components


oClient := TsgcWebSocketClient.Create(nil);
oFXCM := TsgcWSAPI_FXCM.Create(nil);
oFXCM.Client := oClient;
// ... set properties FXCM
oFXCM.FXCM.AccessToken := 'here your access token';
oFXCM.FXCM.Demo := false;
 
// ... connect to server
oClient.Active := True;

Messages
Once authenticated against server, FXCM uses websocket to receive unsolicited messages like price updates and
you can request data from server using HTTP methods.
 

oClient.OnMessage(Connection: TsgcWSConnection; const Text: string);


begin
  // ... here we receive all messages from server
end;

Methods
• GetSymbols: Request a list of all available symbols.
• SubscribeMarketData: After subscribing, market price updates will be pushed to the client via the
socket.
• SubscribeTradingTables: Subscribes to the updates of the data models. Update will be pushed to
client via the socket. Type of update can be determined by "Model" Parameter.
• SnapshotTradingTables: In case continuous updates of the trading tables is not needed, it is possi­
ble to request a one-time snapshot. Gets current content snapshot of the specified data models.
• Model choices:
• Offer
• OpenPosition
• ClosedPosition

428
COMPONENTS

• Order
• Summary
• LeverageProfile
• Account
• Properties
• UpdateSubscriptions: Offers table will show only symbols that we have subscribed to using
update_subscriptions.
• TradingOrder: allows to send open orders, modify, close...
• GetHistoricalData: Allow user to retrieve candles for a given instrument at a given time frame. If time
range is specified, number of candles parameter is ignored, but still required. There is a limit on the
number of candles that can be returned in one request.
 
 

429
COMPONENTS

API 3Commas
3Commas
 

APIs supported
• WebSockets API: connect to a public websocket server and provides real-time market data updates.
• REST API: The REST API has endpoints for account and order management as well as public market data.
 

WebSockets API
The websocket feed provides real-time market data updates for Trades and Deals
 
You can subscribe to the following Public channels:
 
Argu­
Method Description
ments
Sub­
scribeSmart­    
Trades
Sub­
   
scribeDeals
 
These channels requires Authenticate against 3Commas servers. So first request your API keys in your 3Commas
Account and then set the values in the property ThreeComas of the component:
 
• ApiKey
• ApiSecret
 
If the subscription is successful, the event OnThreeCommasConfirmSubscription will be called. If not, the event
OnThreeCommasRejectSubscription it's called, you can get the reason of the rejection using the aRawMessage
parameter.
 

REST API

Test Connectivity

Argu­
Method Description
ments
GetPing    
Get­
Server­   Returns the server time
Time
 

Account

Method Arguments Description


User connected
GetAccounts  
exchanges list

430
COMPONENTS

Supported Market
GetMarketList  
List
aMarketCode:
GetMarket­
code of the All market pairs
Pairs
market
aMarketCode:
GetCurren­ Currency rates and
code of the
cyRatesWith­ limits with leverage
market aPair:
LeverageData data
pair name
aMarketCode:
GetCurren­ code of the Currency rates and
cyRates market aPair: limits
pair name
aAccountId: if Load balances for
GetBalances
of the account specified exchange
Information about
GetAccount­ aAccountId: if all user balances
TableData of the accoun on specified ex­
change
aAccountId: if
GetAc­
of the accoun Information about
countLever­
aPair: pair account leverage
age
name
GetAccountIn­ aAccountId: if
Single Account Info
fo of the accoun
 
 

Smart Trades

Method Arguments Description


GetS­
mart­
  Get the Trade History
Trade­
History
aAccountId: id
of the account
Place­ aOrderSide:
Marke­ buy or sell Places a Market Order
tOrder aPair: pair
name aQuanti­
ty: amount
aAccountId: id
of the account
aOrderSide:
Place­ buy or sell
Limi­ aPair: pair Places a Limit ORder
tOrder name aQuanti­
ty: amount
aPrice: limit
price

431
COMPONENTS

GetS­
aId: id of the Get a Smart Trade by
mart­
trade the Id of the Trade
Trade
CancelS­
aId: id of the Cancel a Smart Trade
mart­
trade by the Id of the Trade
Trade
CloseBy­
MarketS­ aId: id of the
 
mart­ trade
Trade
 

Events
OnConnect
 
When a new WebSocket connection is open
 
OnDisconnect
 
When a WebSocket connection is closed
 
OnThreeCommasConnect
 
When the client receives a Welcome message from 3Commas server, means the connection is ready.
 
OnThreeCommasConfirmSubscription
 
Confirms a previously subscription sent by the client.
 
OnThreeCommasRejectSubscription
 
There is any error trying to subscribe to a 3Commas channel
 
OnThreeCommasMessage
 
Here the client receives the data sent by server related to the channels subscribed
 
OnThreeCommasPing
 
Ping sent by server to the client.
 
OnThreeCommasHTTPException
 
If there is any error while calling HTTP REST methods, this event will be called.

432
COMPONENTS

API Blockchain
Blockchain
 
Blockchain WebSocket API allows developers to receive Real-Time notifications about new transactions and
blocks.
 
Once WebSocket is open you can subscribe to a channel:
 
• SubscribeTransactions: Subscribe to notifications for all new bitcoin transactions.
• UnsubscribeTransactions: UnSubscribe to notifications for all new bitcoin transactions.
 
• SubscribeAddress: Receive new transactions for a specific bitcoin address.
• UnSubscribeAddress: Stop receiving new transactions for a specific bitcoin address.
 
Transactions are received OnNewTransaction Event:
 

{
    "op": "utx",
    "x": {
        "lock_time": 0,
        "ver": 1,
        "size": 192,
        "inputs": [
            {
                "sequence": 4294967295,
                "prev_out": {
                    "spent": true,
                    "tx_index": 99005468,
                    "type": 0,
                    "addr": "1BwGf3z7n2fHk6NoVJNkV32qwyAYsMhkWf",
                    "value": 65574000,
                    "n": 0,
                    "script": "76a91477f4c9ee75e449a74c21a4decfb50519cbc245b388ac"
                },
                "script": "483045022100e4ff962c292705f051c2c2fc519fa775a4d8955bce1a3e29884b2785277999ed02200b537ebd22a9f25f
            }
        ],
        "time": 1440086763,
        "tx_index": 99006637,
        "vin_sz": 1,
        "hash": "0857b9de1884eec314ecf67c040a2657b8e083e1f95e31d0b5ba3d328841fc7f",
        "vout_sz": 1,
        "relayed_by": "127.0.0.1",
        "out": [
            {
                "spent": false,
                "tx_index": 99006637,
                "type": 0,
                "addr": "1A828tTnkVFJfSvLCqF42ohZ51ksS3jJgX",
                "value": 65564000,
                "n": 0,
                "script": "76a914640cfdf7b79d94d1c980133e3587bd6053f091f388ac"
            }
        ]
    }
}

 
• SubscribeBlocks: Receive notifications when a new block is found. Note: if the chain splits you will receive
more than one notification for a specific block height.
• UnSubscribeBlocks: Stop receiving notifications when a new block is found. Note: if the chain splits you
will receive more than one notification for a specific block height.
 
Blocks are received OnNewBlock event:
 

{
    "op": "block",
    "x": {

433
COMPONENTS

        "txIndexes": [
            3187871,
            3187868
        ],
        "nTx": 0,
        "totalBTCSent": 0,
        "estimatedBTCSent": 0,
        "reward": 0,
        "size": 0,
        "blockIndex": 190460,
        "prevBlockIndex": 190457,
        "height": 170359,
        "hash": "00000000000006436073c07dfa188a8fa54fefadf571fd774863cda1b884b90f",
        "mrklRoot": "94e51495e0e8a0c3b78dac1220b2f35ceda8799b0a20cfa68601ed28126cfcc2",
        "version": 1,
        "time": 1331301261,
        "bits": 436942092,
        "nonce": 758889471
    }
}

434
COMPONENTS

API Telegram
Telegram
 
Telegram offers two kinds of APIs, one is Bot API which allows to create programs that use Bots and HTTPs as
protocol. Telegram API and TDLib allows to build customized Telegram clients and is much more powerful than
Bot API.
 
sgcWebSockets supports TDLib through tdjson library, which means that you can build your own telegram client.
TDLib takes care of all network implementation details, encryption and local data storage. TDLib supports all
Telegram features.
 
TDLib (Telegram Database Library) Advantages
 
• Cross-platform: can be used on Windows, Android, iOS, MacOS, Linux...
• Easy to use: uses json messages to communicate between application and telegram.
• High-performance: In the Telegram Bot API, each TDLib instance handles more than 24000 bots.
• Consistent: TDLib guarantees that all updates will be delivered in the right order.
• Reliable: TDLib remains stable on slow and unreliable internet connections.
• Secure: All local data is encrypted using a user-provided encryption key.
• Fully Asynchronous: Requests to TDLib don't block each other. Responses will be sent when they are
available.
 

Configuration
Windows
 
TDLib requires other third-parties libraries: OpenSSL and ZLib. These libraries must be deployed with tdjson library.
 
* Windows versions requires VCRuntime which can be download from microsoft: https://www.microsoft.com/en-us/
download/details.aspx?id=52685
 
Copy the following libraries in the same directory where is your application:
 
Windows 32 Windows 64
tdjson.dll tdjson.dll
libcrypto-1_1-
libcrypto-1_1.dll
x64.dll
libssl-1_1.dll libssl-1_1-x64.dll
zlib1.dll zlib1.dll
 
 
OSX64
 
Deploy the library libtdjson.dylib to your device and you can set where is the library using SetTDJsonPath, exam­
ple:
 
if you deploy to "Contents\MacOS\", you must set the path in System.SysUtils.GetCurrentDir folder.
 
Linux64
 
Deploy the library libtdjson.so to your device and set the library path calling the method SetTDJsonPath.
 
Android
 
Deploy the library libtdjsonandroid.so to your device. Example: if you deploy an Android64 library, set RemotePath
in Project/Deployment to "library\lib\arm64-v8a\". If is Android32, set RemotePath to "library\lib\armeabi-v7a\"
 

435
COMPONENTS

iOS64
 
Copy the library libtdjson.a to these directories:
• C:\Program Files (x86)\Embarcadero\Studio\<IDE Version>\lib\iosDevice64\debug
• C:\Program Files (x86)\Embarcadero\Studio\<IDE Version>\lib\iosDevice64\release
 
 

Creating your Telegram Application


In order to obtain an API id and develop your own application using the Telegram API you need to do the following:
 
• Sign up for Telegram using any application.
• Log in to your Telegram core: https://my.telegram.org.
• Go to API development tools and fill out the form.
• You will get basic addresses as well as the api_id and api_hash parameters required for user authorization.
• For the moment each number can only have one api_id connected to it.
 
These values must be set in Telegram.API property of Telegram component. In order to authenticate, you can au­
thenticate as an user or as a bot, there are 2 properties which you can set to login to Telegram:
 
• PhoneNumber: if you login as an user, you must set your phone number (with international code), exam­
ple: +34699123456
• BotToken: if you login as a bot, set your token in this property (as provided by telegram).
• DatabaseDirectory: allows to specify where is the tdlib database. Leave empty and will take the default
configuration.
 
The following parameters can be configured:
 
• ApplicationVersion: application version, example: 1.0
• DeviceModel: device model, example: desktop
• LanguageCode: user language code, example: en.
• SystemVersion: verison of operating system, example: windows.
 
Optionally, you can configure the path where is located tdjson library using SetTDJsonPath method. Just pass the
path before start a new telegram session.
 
Once you have configured Telegram Component, you can set Active property to true and program will try to con­
nect to Telegram.
 
Sample Code

oTelegram := TsgcTDLib_Telegram.Create(nil);
oTelegram.Telegram.API.ApiHash := 'your api hash';
oTelegram.Telegram.API.ApiId := 'your api id';
oTelegram.PhoneNumber := 'your phone number';
oTelegram.ApplicationVersion := '1.0';
oTelegram.DeviceModel := 'Desktop';
oTelegram.LanguageCode := 'en';
oTelegram.SystemVersion := 'Windows';
oTelegram.Active := true;

Authorization
There are two events which can be called by library in order to get an Authentication Code (delivered in Telegram
Application, not SMS) or to provide a password.
 
OnAuthenticationCode
 
This event is called when Telegram sends an Authorization Code to Telegram Application and user must copy this
code and set in Code argument of this event.
 

436
COMPONENTS

procedure OnAuthenticationCode(Sender: TObject; var Code: string);


begin
  Code := InputBox('Telegram Code', 'Introduce code', '');
end;

 
In Android, inputbox doesn't locks the thread, so instead of return the value introduced by user in Code parameter,
use the method SetAuthenticationCode to set the code value.
 

procedure OnAuthenticationCode(Sender: TObject; var Code:string);


begin
  InputBox('Telegram', 'Introduce Telegram Code', '',
    procedure(const AResult: TModalResult; const AValue: string)
    begin
      sgcTelegram.SetAuthenticationCode(AValue);
    end
    );
end;

 
OnAuthenticationPassword
 
This event is called when Telegram requires that user set a password.
 
 

Authorization Status
Once authorization has started, you can check the status of authorization OnAuthorizationStatus event, this event
is called every time there is a change in status of authorization. Some values of Status are:
 
• authorizationStateWaitTdlibParameters
• authorizationStateWaitEncryptionKey
• authorizationStateWaitPhoneNumber
• authorizationStateWaitCode
• authorizationStateLoggingOut
• authorizationStateClosed
• authorizationStateReady
 

Connection Status
Once connection has started, you can check the status of connection OnConnectionStatus event, this event is
called every time there is a change in status of connection. Some values of Status are:
 
• connectionStateConnecting
• connectionStateUpdating
• connectionStateReady
 

Methods
TsgcTDLib_Telegram API Component support the most following methods.
 
Method Parameters Description
aChatId: Id of Chat
which message will be
Send­
sent aText: Text of Mes­ Sends a Text Message
TextMes­
sage. aInlineKeyboard: to a Chat
sage
Optional Buttons (only
bots).

437
COMPONENTS

Sends a Rich Text


Message to a Chat.
aChatId: Id of Chat
Markdown syntax:
which message will be
SendRich­ • Bold: **bold**
sent aText: Text of Mes­ • Italic: __italic__
TextMes­
sage. aInlineKeyboard: • Strike: --strike--
sage
Optional Buttons (only • Underline:
bots). ~~underline~~
• Code:
##code##
aChatId: Id of Chat
which message will be
SendDocu­
sent aFilePath: full file Sends a Document to
mentMes­
path of document aIn­ a Chat.
sage
lineKeyboard: Optional
Buttons (only bots).
aChatId: Id of Chat
which message will be
sent aFilePath: full file
SendPho­ path of photo aWidth: Sends a Photo to a
toMessage witdh of photo. aHeight: Chat.
width of photo. aIn­
lineKeyboard: Optional
Buttons (only bots).
aChatId: Id of Chat
which message will be
sent aFilePath: full file
path of video aWidth:
Send­
witdh of video. aHeight: Sends a Video to a
VideoMes­
width of video. aDura­ Chat.
sage
tion: duration of video
in seconds. aInlineKey­
board: Optional Buttons
(only bots).
aChatId: Id of Chat
which message will be Adds a new member
sent aUserId: Identifier to a chat. Members
of the user. aFor­ can't be added to pri­
wardLimit: The number vate or secret chats.
AddChat­
of earlier messages Members will not be
Member
from the chat to be for­ added until the chat
warded to the new state has been syn­
member; up to 100. Ig­ chronized with the
nored for supergroups server.
and channels.
Adds multiple new
members to a chat.
Currently this option is
aChatId: Id of Chat
only available for su­
which message will be
AddChat­ pergroups and chan­
sent aUserIds: Identi­
Members nels. This option can't
fiers of the users to be
be used to join a chat.
added to the chat.
Members can't be
added to a channel if it
has more than 200

438
COMPONENTS

members. Members
will not be added until
the chat state has
been synchronized
with the server.
Returns information
GetChat­ aChatId: Chat Identifier.
about a single mem­
Member aUserId: User Identifier.
ber of a chat.
GetBasic­ Returns full informa­
aGroupId: Basic Group
Group­ tion about a basic
Identifier
FullInfo group by its identifier.
aSuperGroupId: Identi­
fier of the supergroup or
channel. aSupergroup­
MembersFilter: The Returns information
GetSuper­
type of users to return. about members or
groupMem­
By default null aOffset: banned users in a su­
bers
Number of users to skip. pergroup or channel.
aLimit: The maximum
number of users be re­
turned; up to 200.
Uses an invite link to
add the current user to
the chat if possible.
JoinChat­
aLink: Invite link to im­ The new member will
ByIn­
port; not be added until the
viteLink
chat state has been
synchronized with the
server.
Create­
aUserId: Identifier of Creates a new secret
NewSe­
the user. chat.
cretChat
aUserIds: Identifiers of
CreateNew­
the users to be added to Creates a new basic
Basic­
the chat. aTitle: Title of group
GroupChat
the new basic group
aTitle: Title of the new
SuperGroup aIsChan­
CreateNew­
nel: True, if a channel Creates a new super­
Super­
chat should be created. group or channel.
groupChat
aDescription: Chat De­
scription.
aUserId: Identifier of
the user. aForce: If true,
the chat will be created
Returns an existing
CreatePri­ without network request.
chat corresponding to
vateChat In this case all informa­
a given user
tion about the chat ex­
cept its type, title and
photo can be incorrect
aOffsetOrder: Chat or­ Returns an ordered list
der to return chats from of chats. Chats are
GetChats
aOffsetChatId: Chat sorted by the pair (or­
identifier to return chats der, chat_id) in de­

439
COMPONENTS

from aLimit: The maxi­ creasing order (cannot


mum number of chats to be used is logged as
be returned. Bot)
Returns information
GetChat aChatId: Chat identifier about a chat by its
identifier
aChatId: Chat identifier
aFromMessageId:
Identifier of the mes­
sage starting from which
history must be fetched;
use 0 to get results from
Returns messages in
the last message. aOff­
a chat. The messages
GetChatHis­ set: Specify 0 to get re­
are returned in a re­
tory sults from exactly the
verse chronological or­
from_message_id or a
der
negative offset up to 99
to get additionally some
newer messages. aLim­
it:The maximum num­
ber of messages to be
returned
Returns information
GetUser aUserId: User Identifier about a user by their
identifier.
aServer: Server name
of proxy. aPort: Number
of proxy port. aUser­
Name: Username for
logging in; may be emp­
ty. aPassword: Pass­ Adds a HTTP proxy
AddProxy­ word for logging in; may server for network re­
HTTP be empty. aHTTPOnly: quests. Can be called
Pass true, if the proxy before authorization.
supports only HTTP re­
quests and doesn't sup­
port transparent TCP
connections via HTTP
CONNECT method.
aServer: Server name
Adds a MTProto proxy
of proxy. aPort: Number
AddProx­ server for network re­
of proxy port. aSecret:
yMTProto quests. Can be called
The proxy's secret in
before authorization.
hexadecimal encoding.
aServer: Server name
of proxy. aPort: Number
of proxy port. aUser­ Adds a Socks5 proxy
AddProx­ Name: Username for server for network re­
ySocks5 logging in; may be emp­ quests. Can be called
ty. aPassword: Pass­ before authorization.
word for logging in; may
be empty.
En­ Enables a proxy. Only
aId: ID of proxy
ableProxy one proxy can be en­

440
COMPONENTS

abled at a time. Can


be called before au­
thorization.
Disables the currently
Dis­ enabled proxy. Can be
 
ableProxy called before autho­
rization.
Removes a proxy
Remove­
aId: ID of proxy server. Can be called
Proxy
before authorization.
Returns list of proxies
that are currently set
GetProxies  
up. Can be called be­
fore authorization.
Logouts from
Logout  
Telegram.
aRequest: JSON Re­ Send any Request in
TDLibSend
quest. JSON protocol.
 
 
Example How to send a Text Message

oTelegram := TsgcTDLib_Telegram.Create(nil);
oTelegram.Telegram.API.ApiHash := 'your api hash';
oTelegram.Telegram.API.ApiId := 'your api id';
oTelegram.PhoneNumber := 'your phone number';
oTelegram.Active := true;
...
oTelegram.SendTextMessage('1234', 'My First Message from sgcWebSockets');

Example How to send a method not implemented


 
You can Send Any JSON message using TDLibSend method, example: join a telegram chat.

oTelegram := TsgcTDLib_Telegram.Create(nil);
oTelegram.Telegram.API.ApiHash := 'your api hash';
oTelegram.Telegram.API.ApiId := 'your api id';
oTelegram.PhoneNumber := 'your phone number';
oTelegram.Active := true;
...
oTelegram.TDLibSend('{"@type": "joinChat", "chat_id": "1234"}');

Check the following url to know all JSON methods: Telegram JSON API.
 

Events
OnBeforeReadEvent
This event is called when JSON message is received by Telegram API component and is still not processed. Set
Handled property to True if you process this event manually or don't want that event is processed by component.
You can use this event to log all messages too.
 
OnMessageText
This event is called when a New Message Text has been received, read MessageText parameter to access to mes­
sage text properties.
 
• ChatId: Chat Identifier.
• MessageId: Message Identifier.
• SenderUserId: Sender Identifier.
• Text: Text of message.
 
OnMessageDocument

441
COMPONENTS

This event is called when a New Document Message is received. Access to MessageDocument to get access to
Document properties.
 
• ChatId: Chat Identifier.
• MessageId: Message Identifier.
• SenderUserId: Sender Identifier.
• FileName: Name of Document.
• DocumentId: Document Identifier.
• LocalPath: full path to local file if exists.
• MimeType: Mime-type of document.
• Size: Size of Document.
• RemoteDocumentId: Remote Document Identifier.
 
OnMessagePhoto
This event is called when a New Photo Message is received. Access to MessagePhoto to get access to Photo
properties.
 
• ChatId: Chat Identifier.
• MessageId: Message Identifier.
• SenderUserId: Sender Identifier.
• PhotoId: Photo Identifier.
• LocalPath: full path to local file if exists.
• Size: Size of Photo.
• RemotePhotoId: Remote Photo Identifier.
 
OnVideoPhoto
This event is called when a New Video Message is received. Access to MessageVideo to get access to Video prop­
erties.
 
• ChatId: Chat Identifier.
• MessageId: Message Identifier.
• SenderUserId: Sender Identifier.
• VideoId: Photo Identifier.
• LocalPath: full path to local file if exists.
• Width: width of video.
• Height: height of video.
• Duration: duration in seconds of video.
• Size: Size of Video.
• RemoteVideoId: Remote Photo Identifier.
 
OnNewChat
This event is called when a new chat is received.
 
• ChatId: Chat Identifier.
• ChatType: Chat Type (chatTypeSupergroup, chatTypePrivate...)
• Title: Chat name.
• SuperGroupId: Group Id if is a SuperGroup.
• IsChannel: returns if is channel or not.
 
OnNewCallbackQuery
This event is called when a new incoming callback query is received; for bots only.
 
• Id: Unique query identifier.
• SenderUserId: Identifier of the user who sent the query.
• ChatId: Identifier of the chat, in which que query was sent.
• MessageId: Identifier of the message, from which the query originated.
• ChatInstance: Identifier that uniquely corresponds to the chat to which the message was sent.
• PayloadData: the payload from a general callback button.
• Data: Data that was attached to the callback button.
 
OnEvent
This event is called when a new Event is received by API Component. Can be used to process some events not
implemented by API Component.
 
• Event: Event name (events like: updateOption, updateUser...)

442
COMPONENTS

• Text: full JSON message


 
OnException
This event is called if there is any exception when processing Telegram API Data.
 

Properties
MyId: returns the User Identifier of current user.
 

Full Code Sample


Check the following code sample which shows how connect to Telegram API, ask user to introduce a Code (if re­
quired by Telegram API), send a message when connection is ready and Log Text Messages received.

oTelegram := TsgcTDLib_Telegram.Create(nil);
oTelegram.Telegram.API.ApiHash := 'your api hash';
oTelegram.Telegram.API.ApiId := 'your api id';
oTelegram.PhoneNumber := 'your phone number';
oTelegram.ApplicationVersion := '1.0';
oTelegram.DeviceModel := 'Desktop';
oTelegram.LanguageCode := 'en';
oTelegram.SystemVersion := 'Windows';
oTelegram.Active := true;
procedure OnAuthenticationCode(Sender: TObject; var Code: string);
begin
  Code := InputBox('Telegram Code', 'Introduce code', '');
end;
procedure OnMessageText(Sender: TObject; MessageText: TsgcTelegramMessageText);
begin
  Log('Message Received: ' + MessageText.Text);
end;
procedure OnConnectionStatus(Sender: TObject; const Status: string);
begin
  if Status = 'connectionStateReady' then
    oTelegram.SendTextMessage('1234', 'Hello Telegram!');
end;

443
COMPONENTS

Telegram | Send Telegram Message With In­
line Buttons
Telegram API allows to send messages with inline buttons to select options as an answer (this option is only avail­
able for bots).
 
Before you send a message create an instance of the class TsgcTelegramReplyMarkupInlineKeyboard and call
the method AddButtonTypeCallback or AddButtonTypeUrl for every button you want to create.
 
Example
 
Create a new message asking the user if likes or not the message and a link to answer a poll. Process the re­
sponse using OnNewCallbackQuery event.
 

oReplyMarkup := TsgcTelegramReplyMarkupInlineKeyboard.Create;
Try
  oReplyMarkup.AddButtonTypeCallback('Yes', 'I like it');
  oReplyMarkup.AddButtonTypeCallback('No', 'I hate it');
  oReplyMarkup.AddButtonTypeUrl('Poll', 'https://www.yoursite.com/telegram/poll');
  sgcTelegram.SendTextMessage('123456', 'Do you like the message?', oReplyMarkup);
Finally
  oReplyMarkup.Free;
End;

procedure OnNewCallbackQuery(Sender: TObject; CallbackQuery: TsgcTelegramCallbackQuery);


begin
  if CallbackQuery.PayloadData.Data = 'I like it' then
    ShowMessage('yes')
  else
    ShowMessage('no');
end;

444
COMPONENTS

Telegram | Send Bot Message With Buttons


Telegram API allows to send messages with buttons to request data from the user (this option is only available for
bots).
 
Before you send a message create an instance of the class TsgcTelegramReplyMarkupShowKeyboard and call
the method AddButtonTypeRequestLocation, AddButtonTypeRequestPhoneNumber or AddButtonTypeText
for every button you want to create.
 
 
Example
 
Create a new message asking the user to provide the PhoneNumber
 

oReplyMarkup := TsgcTelegramReplyMarkupShowKeyboard.Create;
Try
  oReplyMarkup.AddButtonTypeRequestPhoneNumber('Give me your phone');
  sgcTelegram.SendTextMessage('123456', 'Please provide the information below', nil, oReplyMarkup);
Finally
  oReplyMarkup.Free;
End;

445
COMPONENTS

Telegram | Send Telegram Message Bold


You can highlight text messages using bold, italic and more styles. Use the method SendRichTextMessage, to
send a Text message with style capabilities, this method parses the text message and adds the entities required
automatically to the API Telegram.
 

Markdown Syntax
• Bold [ * ]

**This is Bold**

• Italic [ _ ]

__This is Italic__

• Strike [ - ]

--This is Strike--

• Underline [ ~ ]

~~This is Underline~~

• Code [ # ]

##This is Monospace##

446
COMPONENTS

Telegram | Telegram Chat not found as Bot


When you log as bot, the GetChats method cannot be used, so you don't get All available chats. If it's the first
time you login as Bot and you try to send a message to a known Chat, you will get this error:
 
{"@type":"error","code":5,"message":"Chat not found"}
 
The solution is before send a telegram message, call GetChat method and pass the ChatId as a parameter. Once
you get the Chat data, you can send telegram messages as usual.
 
As a note, you only must call GetChat the FIRST TIME before send a message if you never receive any bot mes­
sage from this chat. If you close the application and start again, there is no need to call first GetChat because the
Chat is already saved on telegram database.

447
COMPONENTS

Telegram | Get SuperGroup Members


Telegram API allows to get information about members of a SuperGroup. Use the method GetSuperGroupMem­
bers to get information about members or banned users in a supergroup or channel. Can be used only if
SupergroupFullInfo.can_get_members is true; additionally, administrator privileges may be required for some filters.
 
By default the method returns All members of the group, but you can filter the members returned using the Filter
parameter. There are the following parameters:
 
    tsgmFilterNone
Default value, means members are not filtered.
 
    tsgmFilterAdministrators
Returns the creator and administrators.
 
    tsgmFilterBanned
Returns users banned from the supergroup or channel; can be used only by administrators.
You can use the argument aSuperGroupMembersQuery to search using a query.
 
    tsgmFilterBots
Returns bot members of the supergroup or channel.
 
    tsgmFilterContacts
Returns contacts of the user, which are members of the supergroup or channel.
You can use the argument aSuperGroupMembersQuery to search using a query.
 
    tsgmFilterMention
Returns users which can be mentioned in the supergroup.
 
    tsgmFilterRecent
Returns recently active users in reverse chronological order.
 
    tsgmFilterRestricted
Returns restricted supergroup members; can be used only by administrators.
You can use the argument aSuperGroupMembersQuery to search using a query.
 
    tsgmFilterSearch
Used to search for supergroup or channel members via a (string) query.
You can use the argument aSuperGroupMembersQuery to search using a query.
 
 
You can read the result of the result using OnEvent callback and filtering by event = "chatMembers".
 

Telegram.GetSupergroupMembers(1452979380);

procedure OnTelegramEvent(Sender: TObject; const Event, Text: string);


begin
  if Event = 'chatMembers' then
    ReadJSON(Text);
end;

448
COMPONENTS

Telegram | Add Telegram Proxy


Telegram Client can be configured to make of use of a proxy. Currently, Telegram supports 3 types of proxies:
 
1. HTTP
2. MTProto
3. Socks5
 

Add Proxy
In order to configure a HTTP Proxy, first you must add the proxy to telegram configuration, to do this, just call Ad­
dProxyHTTP and if successful, a message will be returned with the new proxy added. Once the proxy has been
added to the list, just call EnableProxy and pass the ID of the proxy received on the confirmation message.
 

Telegram.AddProxyHTTP('8.8.8.8', 8080, '', '', True);


// ... read the confirmation message and save the ID of the proxy.
Telegram.EnableProxy(2);

Remove Proxy
Call RemoveProxy method and pass the ID of the proxy you want remove.

449
COMPONENTS

Telegram | Register Telegram User


The process to register a new user in Telegram is very simple, you need your API Id and API Hash, and the phone
number of the new account.
 
Configure the telegram client:
• API Id
• API Hash
• Telephone Number of the new telegram account.
 
Start the client and a new code will be sent to the phone, the client will ask for the telegram code and if it's correct,
the event OnRegisterUser will be called. In this event set the First Name and Last Name of the user and the regis­
tration will be completed.
 

oTelegram := TsgcTDLib_Telegram.Create(nil);
oTelegram.Telegram.API.ApiHash := 'ABCDEFGHIJKLMN';
oTelegram.Telegram.API.ApiId := '1234';
oTelegram.PhoneNumber := '008745744155';
oTelegram.Active := true;

procedure OnTelegramAuthenticationCode(Sender: TObject; var Code: string);


begin
  Code := 'code sent to phone';
end;

procedure OnTelegramRegisterUser(Sender: TObject; var FirstName, LastName: string);


begin
  FirstName := 'first name';
  LastName := 'last name';
end;

450
COMPONENTS

RCON
RCON
 
The Source RCON Protocol is a TCP/IP-based communication protocol used by Source Dedicated Server, which
allows console commands to be issued to the server via a "remote console", or RCON. The most common use of
RCON is to allow server owners to control their game servers without direct access to the machine the server is
running on.
 

Configuration
The RCON_Options allows to configure the following properties:
 
• Host: server remote address.
• Port: server listening port.
• Password: is the secret string used to authenticate against the server
 

Connect
Use the property Active to Connect / Disconnect from server.
When Active is set to True, the client tries to connect to the server, if can connect, it will try to authenticate using the
provided password.
The server will send a response to a Authentication request, the event OnAuthenticate will be called and you can
read if authentication is successful or not using the Authenticate parameter.
 

Send Commands
Use the method ExecCommand to send commands to the server. The responses will be available OnResponse
Event.
 

oRCON := TsgcLib_RCON.Create(nil);
oRCON.RCON_Options.Host := '127.0.0.1';
oRCON.RCON_Options.Port := 25575;
oRCON.RCON_Options.Password := 'test';
oRCON.Active := True;

procedure OnAuthenticate(Sender: TObject; Authenticated: Boolean; const aPacket: TsgcRCON_Packet);


begin
  if Authenticated then
    DoLog('#authenticated')
  else
    DoLog('#not authenticated');
end;

procedure OnResponse(Sender: TObject; const aResponse: string; const aPacket: TsgcRCON_Packet);


begin
  DoLog(aResponse);
end;

451
COMPONENTS

CryptoHopper
CryptoHopper
 
CryptoHopper it's an automated crypto trading bot that allows to automate trading and portfolio management for
Bitcoin, Ethereum, Litecoin and more.
 
 

Configuration
Requires a Developer Account and once you have been approved you can start to create a new App. The API us­
es OAuth2 to authenticate, so you can retrieve the client_id and client_secret from your App.
 

oCryptoHopper := TsgcHTTP_Cryptohopper.Create(nil);
oCryptoHopper.CryptoHopperOptions.OAuth2.ClientId := 'client_id';
oCryptoHopper.CryptoHopperOptions.OAuth2.ClientSecret := 'client_secret';
oCryptoHopper.CryptoHopperOptions.OAuth2.LocalIP := '127.0.0.1';
oCryptoHopper.CryptoHopperOptions.OAuth2.LocalPort := 8080;
oCryptoHopper.CryptoHopperOptions.OAuth2.Scope.Text := "read,notifications,manage,trade";

Methods
CryptoHopper uses HTTPs as the protocol to send Requests to the API. Some methods requires authentication
(place orders, retrieve user data...) and some others are public (get exchange data for example).
 
The functions returns the CryptoHopper response and if there is any error an exception will be raised.
 
Hoppers
 
Manage Basic Hopper Operations.
 
Argu­
Method Description
ments
GetHop­
  Get Hoppers of users.
pers
aBody:
Create­ configura­
Create a new Hopper.
Hopper tion json
text.
GetHop­ aId: hopper
Retrieve Hopper
per id
Delete­ aId: hopper
Delete Hopper
Hopper id
aId: hopper
id aBody:
Update­
configura­ Update Hopper
Hopper
tion json
text.
 
 
Orders
 
Manage the Orders of your Hopper.
 

452
COMPONENTS

Argu­
Method Description
ments
aId: hopper Retrieve all of the open or­
GetOpenOrders
id ders of the hopper.
aId: hopper
id aOrder:
Create new buy or sell or­
Create­ instance of
der. For sell, rather use the
NewOrder Ts­
sell endpoint.
gcHTTPC­
THOrder
aId: hopper
id aOrder­
Side:
cthosBuy or
PlaceMarke­ cthosSell.
Place a Market Order.
tOrder aCoin: coin
name, ex­
ample: EOS
aAmount:
order size.
aId: hopper
id aOrder­
Side:
cthosBuy or
cthosSell.
PlaceLimi­ aCoin: coin Place a Limit Order
tOrder name, ex­
ample: EOS
aAmount:
order size.
aPrice: limit
price.
aId: hopper
id Deletes order for selected
DeleteOrder
aOrderId: hopper.
order id
DeleteAl­ aId: hopper Deletes all open order for
lOrders id selected hopper.
aId: hopper
id Get open order in hopper by
GetOpenOrder
aOrderId: id.
order id
aId: hopper
id
CancelOrder Cancel an open order.
aOrderId:
order id
 
 
Position
 
Manage the Positions of your Hopper.
 
Argu­
Method Description
ments

453
COMPONENTS

GetPo­ aId: hopper


Get open positions of hopper.
sition id
 
 
Trade
 
Trade History from your Hopper.
 
Argu­
Method Description
ments
Get­
Trade­   Get the trade history of the hopper.
History
Get­ aId: hopper
Trade­ id
Get a trade by id of the hopper.
History­ aTradeId:
ById trade id
 
 
Exchange
 
Get Information from available exchanges on CryptoHopper
 
Argu­
Method Description
ments
GetEx­ Get all available exchanges on
 
change Cryptohopper.
aEx­
GetAllTick­ change:
Get ticker for all pairs
ers exchange
name
aEx­
change:
GetMar­ exchange
Get ticker from market pair.
ketTicker name
aPair: pair
name
aEx­
change:
exchange
name Gets the orderbook for the select­
GetOrder­
aPair: pair ed exchange, market and order­
Book
name book depth.
aDepth:  or­
der book
depth
 
 
Webhooks
 
Trade History from your Hopper.
 
Argu­
Method Description
ments
Cre­ aURL: web­
ateWeb­ hook url Update or create a Webhook
hook aMes­

454
COMPONENTS

sageTypes:
message
types sepa­
ted by com­
ma.
DeleteWeb­ aURL: web­
Delete an existing Webhook.
hook hook url
 
 
Signals
 
Send Signals to CryptoHopper API.
 
Argu­
Method Description
ments
aSignal: is
the class
with all the
SendSignal fields re­ Sends a Signal
quired to
send a sig­
nal.
aSignal: is
the class
with all the
SendTestSig­
fields re­ Sends a Test Signal
nal
quired to
send a sig­
nal.
aSignalId:
id of the
signal. aEx­
Retrieve some of the signal sta­
GetSignalStats change:
tistics.
optional,
name of the
exchange.

How Update Cryptohopper Config


Use the UpdateHopper method to update the Hopper Configuration. The method is overloaded so you can pass the
JSON string or use the object TsgcHTTPCTHopper and use the properties to enable or disable the Hopper Proper­
ties.
 

function EnableHopper: string;


var
  oHopper: TsgcHTTPCTHopper;
begin
  oHopper := TsgcHTTPCTHopper.Create;
  Try
    if Cryptohopper.GetHopper('1234', oHopper) then
    begin
      oHopper.Enabled := 1;
      result := Cryptohopper.UpdateHopper('1234', oHopper);
    end;
  Finally
    FreeAndNil(oHopper);

455
COMPONENTS

  End;
end;

How Configure Webhook


Webhook allows to receive notifications when something happens in a hopper. Webhooks require a public HTTPs
Server which will listen in a URL address all messages sent by cryptohopper. The public server needs to be pro­
tected with a SSL certificate (self-signed certificates are not allowed).
 
First you must create a webhook, so configure the Webhook property of Cryptohopper client setting the Host and
Port when the server will be listening. Then configure the certificate in SSLOptions property.
 
Example: The public IP address will be 1.1.1.1 and the listening port will be 443. The certificate is stored as PEM
file with sgc.pem filename and without password.
 

/* OAuth2 */
cryptohopper.CryptohopperOptions.OAuth2.ClientId = 'client_id';
cryptohopper.CryptohopperOptions.OAuth2.ClientSecret := 'client_secret';
cryptohopper.CryptohopperOptions.OAuth2.LocalIP := '127.0.0.1';
cryptohopper.CryptohopperOptions.OAuth2.LocalPort := 8080;
/* Webhook */
cryptohopper.CryptohopperOptions.Webhook.Enabled := True;
cryptohopper.CryptohopperOptions.Webhook.Host := '1.1.1.1';
cryptohopper.CryptohopperOptions.Webhook.Port := 443;
cryptohopper.CryptohopperOptions.Webhook.ValidationCode := '1234';
cryptohopper.CryptohopperOptions.Webhook.SSLOptions.CertFile := 'sgc.pem';
cryptohopper.CryptohopperOptions.Webhook.SSLOptions.KeyFile := 'sgc.pem';
cryptohopper.CryptohopperOptions.Webhook.SSLOptions.RootCertFile := 'sgc.pem';
cryptohopper.CryptohopperOptions.Webhook.SSLOptions.Password := '';
cryptohopper.StartWebhook;

456
COMPONENTS

RTCMultiConnection
RTCMultiConnection
 
RTCMultiConnection is a WebRTC JavaScript library for peer-to-peer applications (screen sharing, audio/video
conferencing, file sharing, media streaming etc.)
 

Configuration
The RTCMultiConnection requires a WebSocket server for Signaling, so link the server property of RTCMultiCon­
nection to a WebSocket Server (like TsgcWebSocketHTTTPServer). Find below the properties you must configure.
 
Server
 
Host: is the public IP address or DNS name of WebSocket server.
Port: is the listening port of WebSocket Server.
 
IceServers
 
Is the configuration of the ICE servers (STUN/TURN) to allow communicate between peers. Example:
 
[
  {
     "urls": "stun:www.yourstun.com"},
  {
    "urls": "turn:www.yourturn.com",
    "username": "user",
    "credential": "secret"
  }
]
 
VideoResolution
 
Here you can configure the Video Resolution of Video Conferences, as higher is the resolution, more bandwidth is
required by the connection.
 
HTMLDocuments
 
Configure for every Application which is the name of the HTML page that servers this content.
 
Example: if the server is running on website www.webrtc.com on port 8443 and the
HTMLDocuments.VideoConferencing = /RTCMultiConnection-VideoConferencing.html, the url to access the Video­
Conferencing will be
 
https://www.webrtc.com:8443/RTCMultiConnection-VideoConferencing.html
 
 
WebRTC requires a secure connection (HTTPs) so requires the use of certificates, read more Server SSL.

Applications

Name Description
Video­
Multi-user (many-to-many) video chat using
Confer­
mesh networking model.
encing
Screen­ Multi-user (one-to-many) screen sharing using
Sharing star topology.

457
COMPONENTS

Video­
Multi-user (one-to-many) video broadcasting
Broad­
using star topology.
casting
 
 
 
 
 

458
COMPONENTS

Extensions
WebSocket protocol is designed to be extended. WebSocket Clients may request extensions and WebSocket
Servers may accept some or all extensions requested by clients.
 
Extensions supported:
 
1. Deflate-Frame: compress WebSocket frames.
 
2. PerMessage-Deflate: compress WebSocket messages.
 
 

459
COMPONENTS

Extensions | PerMessage-Deflate
PerMessage is a WebSocket protocol extension, if the extension is supported by Server and Client, both can com­
press transmitted messages:
 
• Uses Deflate as the compression method.
• Compression only applies to Application data (control frames and headers are not affected).
• Server and client can select which messages will be compressed.
 

Max Window Bits


This extension allows customizing Server and Client size of the sliding window used by LZ77 algorithm (between 8
- 15). As greater is this value, more probably will find and eliminate duplicates but consumes more memory and
CPU cycles. 15 is the default value.
 
 

No Context Take Over


By default, previous messages are used to compression and decompression, if messages are similar, this improves
the compression ratio. If Enabled, then each message is compressed using only its message data. By default is
disabled.
 
 

MemLevel
This value is not negotiated between Server and Client. when set to 1, it uses the least memory, but slows down
the compression algorithm and reduces the compression ratio; when set to 9, it uses the most memory and delivers
the best performance. By default is set to 1.
 
 
 
* Indy version provided with Rad Studio XE2 raises an exception because of zlib version mismatch with initialization
functions, to fix this, just update your Indy version to latest.
 

460
COMPONENTS

Extensions | Deflate-Frame
Is a WebSocket protocol extension which allows the compression of frames sent using WebSocket protocol, sup­
ported by WebKit browsers like chrome or safari. This extension is supported on Server and Client Components.
 
This extension has been deprecated.
 
* Indy version provided with Rad Studio XE2 raises an exception because or zlib version mismatch with initializa­
tion functions, to fix this, just update your Indy version to latest.
 

461
COMPONENTS

IoT
The Internet of things (IoT) refers to the concept of extending Internet connectivity beyond conventional computing
platforms such as personal computers and mobile devices, and into any range of traditionally "dumb" or non-inter­
net-enabled physical devices and everyday objects. Embedded with electronics, Internet connectivity, and other
forms of hardware (such as sensors), these devices can communicate and interact with others over the Internet,
and they can be remotely monitored and controlled.
 
sgcWebSockets package implements the following IoT clients:
 
1. Amazon AWS IoT: AWS IoT provides secure, bi-directional communication between Internet-connected devices
such as sensors, actuators, embedded micro-controllers, or smart appliances and the AWS Cloud. This enables
you to collect telemetry data from multiple devices, and store and analyze the data. You can also create applica­
tions that enable your users to control these devices from their phones or tablets.
 
2. Azure IoT Hub: IoT Hub is a managed service, hosted in the cloud, that acts as a central message hub for bi-di­
rectional communication between your IoT application and the devices it manages. You can use Azure IoT Hub to
build IoT solutions with reliable and secure communications between millions of IoT devices and a cloud-hosted so­
lution backend.
 

462
COMPONENTS

IoT Amazon MQTT Client


What Is AWS IoT?
AWS IoT provides secure, bi-directional communication between Internet-connected devices such as sensors, ac­
tuators, embedded micro-controllers, or smart appliances and the AWS Cloud. This enables you to collect telemetry
data from multiple devices, and store and analyze the data. You can also create applications that enable your users
to control these devices from their phones or tablets.
 

Message broker
Provides a secure mechanism for devices and AWS IoT applications to publish and receive messages from each
other. You can use either the MQTT protocol directly or MQTT over WebSocket to publish and subscribe.
 
The AWS IoT message broker is a publish/subscribe broker service that enables the sending and receiving of mes­
sages to and from AWS IoT. When communicating with AWS IoT, a client sends a message addressed to a topic
like Sensor/temp/room1.
 
The message broker, in turn, sends the message to all clients that have registered to receive messages for that
topic. The act of sending the message is referred to as publishing. The act of registering to receive messages for a
topic filter is referred to as subscribing.
 
The topic namespace is isolated for each AWS account and region pair. For example, the Sensor/temp/room1 topic
for an AWS account is independent from the Sensor/temp/room1 topic for another AWS account. This is true of re­
gions, too. The Sensor/temp/room1 topic in the same AWS account in us-east-1 is independent from the same top­
ic in us-east-2. AWS IoT does not support sending and receiving messages across AWS accounts and regions.
 
The message broker maintains a list of all client sessions and the subscriptions for each session. When a message
is published on a topic, the broker checks for sessions with subscriptions that map to the topic. The broker then for­
wards the publish message to all sessions that have a currently connected client.
 

MQTT Client
TsgcIoTAmazon_MQTT_Client is the component used for connect to AWS IoT, one client can connect to only one
device. Client connects using plain MQTT protocol and authenticates using a X.509 Client Certificate.
 
In order to connect to AWS IoT, client needs the following properties:
 
Amazon.ClientId: identification of client, optional.
Amazon.Endpoint: server name where MQTT client will connect.
Amazon.Port: by default uses port 8883. If port is 443, uses ALPN automatically to connect (Requires cus­
tom Indy version).
 
AWS IoT Core supports devices and clients that use the MQTT and the MQTT over WebSocket Secure (WSS) pro­
tocols to publish and subscribe to messages. The following table lists the protocols that the AWS IoT device end­
points support and the authentication methods and ports they use.
 
ALPN
Authentica­
Protocol Port Protocol
tion
Name
MQTT over Signature
443  
WebSocket Version 4
MQTT over Custom Au­
443  
WebSocket thentication

463
COMPONENTS

X.509 client x-amzn-


MQTT 443
certificate mqtt-ca
X.509 client
MQTT 8883  
certificate
Custom Au­
MQTT 443 mqtt
thentication
 
 

Certificates Authentication
Requires to create certificates in your Amazon AWS console and set the path were are stored.
 
Using OpenSSL as IOHandler you must set the certificate in the following paths
 
Certificate.Enabled: set to True if you want use certificates.
Certificate.CertFile: path to X.509 client certificate.
Certificate.KeyFile: path to X.509 client key file.
 
Using SChannel as IOHandler, first convert the PEM Certificate + Key to a PFX certificate, requires openssl bina­
ries:
 

openssl pkcs12 -inkey 884ccf73ff-private.pem.key -in 884ccf73ff-certificate.pem.crt -export -out 884ccf73ff-certificate

Then set the following paths (there is no need to set the keyfile because is already included in the certificate).
 
Certificate.Enabled: set to True if you want use certificates.
Certificate.CertFile: path to PFX certificate
 

SignatureV4 Authentication
Requires create an user in your Amazon AWS console and save the Access and Secret key which will be used to
Sign the WebSocket request.
 
SignatureV4.Enabled: set to True if you want use this type of Authentication.
SignatureV4.Region: the region were is located your device (example: us-east-1).
SignatureV4.AccessKey: the access key created in your amazon console or get as temporary credential
SignatureV4.SecretKey: the secret key created in your amazon console  or get as temporary credential
SignatureV4.SessionToken: (conditional) if you are using Temporary Security Credentials, set here the se­
curity token.
OpenSSL_Options: configuration of the openSSL libraries.
APIVersion: allows to define which OpenSSL API will be used.
oslAPI_1_0: uses API 1.0 OpenSSL, it's latest supported by Indy
oslAPI_1_1: uses API 1.1 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 1.1.1 libraries (with TLS 1.3 support).
oslAPI_3_0: uses API 3.0 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 3.0.0 libraries (with TLS 1.3 support).
LibPath: here you can configure where are located the openSSL libraries
oslpNone: this is the default, the openSSL libraries should be in the same folder where is the
binary or in a known path.
oslpDefaultFolder: sets automatically the openSSL path where the libraries should be located
for all IDE personalities.
oslpCustomFolder: if this is the option selected, define the full path in the property LibPath­
Custom.
LibPathCustom: when LibPath = oslpCustomFolder define here the full path where are located the
openSSL libraries.
UnixSymLinks: enable or disable the loading of SymLinks under Unix systems (by default is en­
abled, except under OSX64):

464
COMPONENTS

oslsSymLinksDefault: by default are enabled except under OSX64 (after MacOS Monterey
fails trying to load the library without version.).
oslsSymLinksLoadFirst: Load SymLinks and do before trying to load the version libraries.
oslsSymLinksLoad: Load SymLinks after trying to load the version libraries.
oslsSymLinksDontLoad: don't load the SymLinks.
 
*SignatureV4 requires Indy 10.5.7+

Custom Authentication
Custom authentication enables you to define how to authenticate and authorize clients by using authorizer re­
sources. The device passes credentials in either the request’s header fields or query parameters (for MQTT over
WebSockets protocols) or in the user name and password field of the MQTT CONNECT message (for the MQTT
and MQTT over WebSockets protocols).
 
CustomAuthentication.Enabled: set to True if you want to use this type of Authentication.
CustomAuthentication.Parameters: set here the query parameters which will be passed to the server (by
default is /mqtt)
CustomAuthentication.Headers: here you can put the custom header fields.
CustomAuthentication.WebSockets: if set to true, the connection will work over WebSocket protocol, oth­
erwise will work over plain TCP.
 
MQTTAuthentication.Enabled: if you need to pass the username/password in the mqtt connection, enable
this property
MQTTAuthentication.Username: username of the mqtt connection
MQTTAuthentication.Password: secret of the mqtt connection.
 
 
Client can send optionally a ClientId to identifiy client connection, then others clients can subscribe to receive a no­
tification every time this client has connected, subscribed, disconnected...
 

Authorization
If you can't connect using port 8883 and use TCP as transport (which is the default), amazon takes "AWS IoT Core
policy" to provide or not authorization to clients and subscriptions. Most probably you must authorize your client id.
Enter in your Amazon AWS console, go to IoT Core and access the menu "Secure/Policies", there select the policy
attached to your IoT Thing and check at the end how connection is configured. Example:
 
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect"
      ],
      "Resource": [
        "arn:aws:iot:us­east-1:222178873557:client/sdk-java",
        "arn:aws:iot:us­east-1:222178873557:client/basicPubSub",
        "arn:aws:iot:us­east-1:222178873557:client/sdk-nodejs-*"
      ]
    }
 
This configuration means that only clients with ID: sdk-java, basicPubSub and sdk-nodejs-* will be allowed to con­
nect. Change accordingly and try again.
If it still doesn't work, enable log and check in cloudwatch the reason why you can't connect.
 

Other properties
 
     MQTTHeartBeat: if enabled try to keeps alive MQTT connection sending a ping every x seconds.
 
Interval: number of seconds between each ping.
 

465
COMPONENTS

     MQTTAuthentication: if enabled includes in MQTT connection the username and password


 
UserName: name of the user
Password: secret string
 
     WatchDog: if enabled, when an unexpected disconnection is detected, tries to reconnect to the server automati­
cally.
 
Interval: seconds before reconnects.
 
Attempts: max number of reconnects, if zero, then unlimited.
 
     LogFile: if enabled save socket messages to a specified log file, useful for debugging. The access to log file is
not thread safe if it's accessed from several threads.
 
Enabled: if enabled every time a message is received and sent by socket it will be saved on a file.
 
FileName: full path to the filename.
 

Implementation
 
Amazon MQTT implementation is based on MQTT version 3.1.1 but it deviates from the specification as follows:
 
• In AWS IoT, subscribing to a topic with Quality of Service (QoS) 0 means a message is delivered zero or
more times. A message might be delivered more than once. Messages delivered more than once might be
sent with a different packet ID. In these cases, the DUP flag is not set.
• AWS IoT does not support publishing and subscribing with QoS 2. The AWS IoT message broker does not
send a PUBACK or SUBACK when QoS 2 is requested.
• When responding to a connection request, the message broker sends a CONNACK message. This mes­
sage contains a flag to indicate if the connection is resuming a previous session. The value of this flag might
be incorrect if two MQTT clients connect with the same client ID simultaneously.
• When a client subscribes to a topic, there might be a delay between the time the message broker sends a
SUBACK and the time the client starts receiving new matching messages.
• The MQTT specification provides a provision for the publisher to request that the broker retain the last mes­
sage sent to a topic and send it to all future topic subscribers. AWS IoT does not support retained mes­
sages. If a request is made to retain messages, the connection is disconnected.
• The message broker uses the client ID to identify each client. The client ID is passed in from the client to the
message broker as part of the MQTT payload. Two clients with the same client ID are not allowed to be con­
nected concurrently to the message broker. When a client connects to the message broker using a client ID
that another client is using, a CONNACK message is sent to both clients and the currently connected client
is disconnected.
• On rare occasions, the message broker might resend the same logical PUBLISH message with a different
packet ID.
• The message broker does not guarantee the order in which messages and ACK are received.
 

Connect to AWS IoT


First, you must sign in your AWS console, register a new device and create a X.509 certificate for this device. Once
is done, you can create create a new TsgcIoTAmazon_MQTT_Client and connect to AWS IoT Server. For example:
 

oClient := TsgcIoTAmazon_MQTT_Client.Create(nil);
oClient.Amazon.Endpoint := 'a2ohgdjqitsmij-ats.iot.us-west-2.amazonaws.com';
oClient.Amazon.ClientId := 'sgcWebSockets';
oClient.Certificate.CertFile := 'amazon-certificate.pem.crt';
oClient.Certificate.KeyFile := 'amazon-private.pem.key';
oClient.OnMQTTConnect := OnMQTTConnectEvent;
oClient.Active := True;
 
procedure OnMQTTConnect(Connection: TsgcWSConnection; const Session: Boolean; const ReturnCode: TmqttConnReturnCode)
begin
  ShowMessage('Connected to AWS');
end;

466
COMPONENTS

Topics
The message broker uses topics to route messages from publishing clients to subscribing clients. The forward
slash (/) is used to separate topic hierarchy. The following table lists the wildcards that can be used in the topic filter
when you subscribe. # Must be the last character in the topic to which you are subscribing. Works as a wildcard by
matching the current tree and all subtrees.
For example, a subscription to Sensor/# receives messages published to Sensor/, Sensor/temp, Sensor/temp/
room1, but not the messages published to Sensor.
+ Matches exactly one item in the topic hierarchy. For example, a subscription to Sensor/+/room1 receives mes­
sages published to Sensor/temp/room1, Sensor/moisture/room1, and so on.
 

oClient := TsgcIoTAmazon_MQTT_Client.Create(nil);
...
oClient.OnSubscribe := OnSubscribeEvent;
 
vPacketIdentifier := oClient.Subscribe('Sensor/moisture/room1');
  
procedure OnMQTTSubscribe(Connection: TsgcWSConnection; aPacketIdentifier: Word; aCodes: TsgcWSSUBACKS);
begin
  if vPacketIdentifier = aPacketIdentifier then
    ShowMessage('Subscribed to topic Sensor/moisture/room1');
end;
 
// Client, can send a message using Publish method.
oClient.Publish('Sensor/moisture/room1', '{"temp"=10}');
  
// Messages received from server, are dispatched OnMQTTPublishEvent.
procedure OnMQTTPublish(Connection: TsgcWSConnection; aTopic, aText: string);
begin
  DoLog('Received Message: ' + aTopic + ' ' + aText);
end;

Reserved Topics
Following methods are used to subscribe / publish to reserved topics.
 
    Subscribe_ClientConnected(const aClientId: String): AWS IoT publishes to this topic when an MQTT client
with the specified client ID connects to AWS IoT
    Subscribe_ClientDisconnected(const aClientId: String): AWS IoT publishes to this topic when an MQTT
client with the specified client ID disconnects to AWS IoT
    Subscribe_ClientSubscribed(const aClientId: String): AWS IoT publishes to this topic when an MQTT client
with the specified client ID subscribes to an MQTT topic
    Subscribe_ClientUnSubscribed(const aClientId: String): AWS IoT publishes to this topic when an MQTT
client with the specified client ID unsubscribes to an MQTT topic
 
    Publish_Rule(const aRuleName, aText: String): A device or an application publishes to this topic to trigger
rules directly
 
    Publish_DeleteShadow(const aThingName, aText: String): A device or an application publishes to this topic
to delete a shadow
    Subscribe_DeleteShadow(const aThingName: String): A device or an application subscribe to this topic to
delete a shadow
    Subscribe_ShadowDeleted(const aThingName: String): The Device Shadow service sends messages to this
topic when a shadow is deleted
    Subscribe_ShadowRejected(const aThingName: String): The Device Shadow service sends messages to
this topic when a request to delete a shadow is rejected
    Publish_ShadowGet(const aThingName, aText: String): An application or a thing publishes an empty mes­
sage to this topic to get a shadow
    Subscribe_ShadowGet(const aThingName: String): An application or a thing subscribe to this topic to get a
shadow
    Subscribe_ShadowGetAccepted(const aThingName: String): The Device Shadow service sends messages
to this topic when a request for a shadow is made successfully
    Subscribe_ShadowGetRejected(const aThingName: String): The Device Shadow service sends messages
to this topic when a request for a shadow is rejected
    Publish_ShadowUpdate(const aThingName, aText: String): A thing or application publishes to this topic to
update a shadow

467
COMPONENTS

    Subscribe_ShadowUpdateAccepted(const aThingName: String): The Device Shadow service sends mes­


sages to this topic when an update is successfully made to a shadow
    Subscribe_ShadowUpdateRejected(const aThingName: String): The Device Shadow service sends mes­
sages to this topic when an update to a shadow is rejected
    Subscribe_ShadowUpdateDelta(const aThingName: String): The Device Shadow service sends messages
to this topic when a difference is detected between the reported and desired sections of a shadow
    Subscribe_ShadowUpdateDocuments(const aThingName: String): AWS IoT publishes a state document to
this topic whenever an update to the shadow is successfully performed
 

Persistent Sessions
A persistent session represents an ongoing connection to an MQTT message broker. When a client connects to the
AWS IoT message broker using a persistent session, the message broker saves all subscriptions the client makes
during the connection. When the client disconnects, the message broker stores unacknowledged QoS 1 messages
and new QoS 1 messages published to topics to which the client is subscribed. When the client reconnects to the
persistent session, all subscriptions are reinstated and all stored messages are sent to the client at a maximum rate
of 10 messages per second.
 
You create an MQTT persistent session setting the cleanSession parameter to False OnMQTTBeforeConnect
event. If no session exists for the client, a new persistent session is created. If a session already exists for the
client, it is resumed.
 
Devices need to look at the Session attribute in the OnMQTTConnect event to determine if a persistent session is
present. If Session is True, a persistent session is present and stored messages are delivered to the client. If Ses­
sion is False, no persistent session is present and the client must re-subscribe to its topic filters.
 
Persistent sessions have a default expiry period of 1 hour. The expiry period begins when the message broker de­
tects that a client disconnects (MQTT disconnect or timeout). The persistent session expiry period can be in­
creased through the standard limit increase process. If a client has not resumed its session within the expiry period,
the session is terminated and any associated stored messages are discarded. The expiry period is approximate,
sessions might be persisted for up to 30 minutes longer (but not less) than the configured duration.
 

Temporary Credentials
AWS IoT Core can work with Temporary Credentials obtained through Identity Pools, there are 2 types of Identities:
 
• UnAuthenticated: only requires to set the policy type in the IAM
• Authenticated: requires to set the policy type in IAM and AWS IoT Core policies
 

Unauthenticated

If you are using Unauthenticated credentials, just attach the policy in the UnAuthenticated Role automatically creat­
ed in the IAM menu. Then configure the client setting the Access, Secret Key and Token returned by Cognito ser­
vice.
Find below a code in .NET to get unauthenticated credentials
 

CognitoAWSCredentials credentials = new CognitoAWSCredentials(


    "us-east-1:cc3c9c48-646d-44ef-bfd5-0c5fb2f0882f", // Identity pool ID
    Amazon.RegionEndpoint.USEast1 // Region
);
 
var identityPoolId = credentials.GetCredentialsAsync();
 
AmazonCognitoIdentityClient cognitoClient = new AmazonCognitoIdentityClient(
    credentials, // the anonymous credentials
    Amazon.RegionEndpoint.USEast1 // the Amazon Cognito region
);
 
GetIdRequest idRequest = new GetIdRequest();
idRequest.AccountId = "222178873557";
idRequest.IdentityPoolId = "us-east-1:cc3c9c48-646d-44ef-bfd5-0c5fb2f0882f";
 

468
COMPONENTS

GetIdResponse idResp = cognitoClient.GetId(idRequest);


 
string AccessKey = identityPoolId.Result.AccessKey;
string SecretKey = identityPoolId.Result.SecretKey;
string SessionToken = identityPoolId.Result.Token;
 
string IdentityId = idResp.IdentityId;

Authenticated

Authenticated credentials, requires to attache de policy in the Authenticated Role automatically created in the IAM
menu and attach the policy of the user in AWS IoT Core policies.
So create a new policy in the IoT Core policies menu and every time a new user authenticates, attach this policy to
this user.
You can use the following command of AWS to attach a policy or create a lambda function.
 
aws iot attach-policy --policy-name PolicyName --target us-east-1:XXXXX-XXXX-XXXX-
XXXX-XXXXXXXXXXXX

469
COMPONENTS

IoT Azure MQTT Client


What is Azure IoT Hub?
IoT Hub is a managed service, hosted in the cloud, that acts as a central message hub for bi-directional communi­
cation between your IoT application and the devices it manages. You can use Azure IoT Hub to build IoT solutions
with reliable and secure communications between millions of IoT devices and a cloud-hosted solution backend. You
can connect virtually any device to IoT Hub.
 
IoT Hub supports communications both from the device to the cloud and from the cloud to the device. IoT Hub sup­
ports multiple messaging patterns such as device-to-cloud telemetry, file upload from devices, and request-reply
methods to control your devices from the cloud. IoT Hub monitoring helps you maintain the health of your solution
by tracking events such as device creation, device failures, and device connections.
 
IoT Hub's capabilities help you build scalable, full-featured IoT solutions such as managing industrial equipment
used in manufacturing, tracking valuable assets in healthcare, and monitoring office building usage.
 

Message broker
IoT Hub gives you a secure communication channel for your devices to send data. IoT Hub and the device SDKs
support the following protocols for connecting devices:
 
• MQTT
• MQTT over WebSockets
 
Multiple authentication types support a variety of device capabilities:
 
• SAS token-based authentication to quickly get started with your IoT solution.
• Individual X.509 certificate authentication for secure, standards-based authentication.
 
 

MQTT Client
TsgcIoTAzure_MQTT_Client is the component used for connect to Azure IoT, one client can connect to only one
device. Client connects using plain MQTT protocol and authenticates using SAS / X.509 Client Certificate.
 
In order to connect to Azure IoT Hub, client needs the following properties:
 
Azure.IoTHub: server name where MQTT client will connect.
Azure.DeviceId: name of device in azure IoT Hub.
 
Azure allows multiple authentication types, by default uses SAS tokens.
 
SAS Authentication
 
SAS.Enabled: enable if authentication uses SAS.
SAS.SecretKey: here SAS Token from your Azure IoT Account.
SAS.Expiry: set the number of minutes before SAS Token expires. Default value is 1440 (24 hours).
 
X509 Certificates
 
Using OpenSSL as IOHandler
 
Certificate.Enabled: enable if authentication uses certificates.
Certificate.CertFile: path to X.509 client certificate.
Certificate.KeyFile: path to X.509 client key file.
Certificate.Password: if certificate has a password set here.

470
COMPONENTS

Version: TLS version, by default uses TLS 1.0


 
Using SChannel as IOHandler
 
Certificate.Enabled: enable if authentication uses certificates.
Certificate.CertFile: path to PFX certificate (first the certificate must be converted to PFX). Read More.
Certificate.Password: if certificate has a password set here.
Version: TLS version, by default uses TLS 1.0
 
Other properties:
 
     MQTTHeartBeat: if enabled try to keeps alive MQTT connection sending a ping every x seconds.
 
Interval: number of seconds between each ping.
 
     WatchDog: if enabled, when an unexpected disconnection is detected, tries to reconnect to the server automati­
cally.
 
Interval: seconds before reconnects.
 
Attempts: max number of reconnects, if zero, then unlimited.
 
     LogFile: if enabled save socket messages to a specified log file, useful for debugging. The access to log file is
not thread safe if it's accessed from several threads.
 
Enabled: if enabled every time a message is received and sent by socket it will be saved on a file.
 
FileName: full path to the filename.
 
 
Azure MQTT implementation is based on MQTT version 3.1.1 but it deviates from the specification as follows:
 
• IoT Hub does not support QoS 2 messages. If a device app publishes a message with QoS 2, IoT Hub clos­
es the network connection.
• IoT Hub does not persist Retain messages. If a device sends a message with the RETAIN flag set to 1, IoT
Hub adds the x-opt-retain application property to the message. In this case, instead of persisting the retain
message, IoT Hub passes it to the backend app.
• IoT Hub only supports one active MQTT connection per device. Any new MQTT connection on behalf of the
same device ID causes IoT Hub to drop the existing connection.
 

Connect to Azure IoT Hub


First, you must sign in your Azure account, register a new device and create an authentication method for this de­
vice. Once is done, you can create create a new TsgcIoTAzure_MQTT_Client and connect to Azure IoT Hub.
 
For example:

oClient := TsgcIoTAzure_MQTT_Client.Create(nil);
oClient.Azure.IoTHub := 'youriothub.azure-devices.net';
oClient.Azure.DeviceId := 'YourDeviceId';
oClient.SAS.Enabled := True;
oClient.SAS.SecretKey := 'YourSecretKey';
oClient.OnMQTTConnect := OnMQTTConnectEvent;
oClient.Active := True;
 
procedure OnMQTTConnect(Connection: TsgcWSConnection; const Session: Boolean; const
ReturnCode: TmqttConnReturnCode);
begin
  ShowMessage('Connected to Azure IoT Hub');
end;

Device To Cloud
When sending information from the device app to the solution back end, IoT Hub exposes following options:
 

471
COMPONENTS

1. Device-to-cloud messages for time series telemetry and alerts.

oClient.Send_DeviceToCloud('{"temp"=10}', azuIoTQoS1);

You can send key-value properties using a TStringList, just fill the TStringList with the desired message properties
and pass these as argument.

oProperties := TStringList.Create;
Try
  oProperties.AddPair('prop_name1', 'prop_value1');
  oProperties.AddPair('prop_name2', 'prop_value2');
  oClient.Send_DeviceToCloud('{"temp"=10}', oProperties, azuIoTQoS1);
Finally
  oProperties.Free;
End;

If you need to set the ContentType and ContentEncoding of the message, you must add the these values to the
Properties List, the name of these properties are defined by Azure.
 
Name Value
$.ct application/json
$.ce utf-8
 

oProperties := TStringList.Create;
Try
  oProperties.AddPair('$.ct', 'application/json');
  oProperties.AddPair('$.ce', 'utf-8');
  oClient.Send_DeviceToCloud('{"temp"=10}', oProperties, azuIoTQoS1);
Finally
  oProperties.Free;
End;

 
 
2. Device twin's reported properties for reporting device state information such as available capabilities, condi­
tions, or the state of long-running workflows. For example, configuration and software updates.

oClient.Set_DeviceTwinsProperties('1', '{"sgc":1}');

Cloud To Device
IoT Hub provides three options for device apps to expose functionality to a back-end app:
 
1. Direct methods for communications that require immediate confirmation of the result.  Direct methods are often
used for interactive control of devices such as turning on a fan.

oClient.Subscribe_DirectMethod;

You can respond to public methods, using following method.

oClient.RespondPublicMethod(RequestId, Status, 'Your Response', azuIoTQoS1);

2. Twin's desired properties for long-running commands intended to put the device into a certain desired state.
 For example, set the telemetry send interval to 30 minutes. You can get Properties using following method.

oClient.Get_DeviceTwinsProperties('1');

3. Cloud-to-device messages for one-way notifications to the device app. To get messages, first you must sub­
scribe.

472
COMPONENTS

oClient.Subscribe_CloudToDevice;

Messages are received OnMQTTPublish event.

procedure TFRMSGCClientIoT.AzureIoTMQTTPublish(Connection: TsgcWSConnection; aTopic, aText: string);


begin
  DoLog('Received Message: ' + aTopic + ' ' + aText);
end;

473
COMPONENTS

HTTP
HTTP protocol allows to fetch resources from servers like images, html documents...it's a slicent-server protocol
which means that client request to server which resources need.
 
When a client wants connect to a server, follows next steps:
 
1. Open a new TCP connection
2. Sends a message to server with data requested
 

GET / HTTP/1.1
Host: server.com
Accept-Language: en-us

 
3. Read response sent by server
 

HTTP/1.1 200 OK
Server: Apache
Content-Length: 120
Content-Type: text/html
 
...

Components
 
• HTTP/2: HTTP/2 (or h2) is a binary protocol that brings push, multiplexing streams and frame control to the
web.
• HTTP/1 Client: non-visual component that inherits from TIdHTTP client component.
• OAuth2: OAuth2 allows third-party applications to receive a limited access to an HTTP service
• JWT: JWT allows creating data with optional signature and/or encryption whose Payloads holds JSON that
asserts some number of claims.
• Amazon SQS: is a fully managed message queues for microservices, distributed systems, and serverless
applications.
• Google Cloud Pub/Sub: provides messaging between applications and is designed to provide reliable,
many-to-many, asynchronous messaging between applications.
• Google Calendar: allows to use Google Calendar API V3: get Calendars, events, synchronize with your
own calendar...

474
COMPONENTS

HTTP/2
HTTP/2 is an evolution of the HTTP 1.1 protocol, basically tries to be more efficient using networks. The semantics
are the same, so it's designed to be compatible with old protocols.
 

HTTP 1.1 Limitations


HTTP 1.1 is limited to process one request per connection, so usually clients use more than one connection to re­
quest files to servers. But this arise a problem, because when there are too many open TCP connections, there is a
race between clients to use the server resources and performance is lower and lower as much clients connect to
servers.

Main features
• HTTP/2 is a binary protocol (remember that HTTP 1.1 is a text protocol).
• HTTTP/2 works over TLS and ALPN.
• It's multiplexed (allows to send more than one request over a single TCP Conenction).
• Server can push responses to clients.
• Reduces Round Trip Times, so clients can load faster.
 
HTTP/2 introduces other improvements, more details: RFC7540.
 
HTTP/2 requires our custom Indy version because requires ALPN protocol.
 

Components
• TsgcHTTP2Client: client component that fully supports HTTP/2 protocol (sgcWebSockets 100% Pascal
code, without external libraries).
• TsgcWebSocketHTTPServer: server component that fully supports HTTP/2 protocol (sgcWebSockets
100% Pascal code, without external libraries). By default HTTP/2 is disabled, you can enable using
HTTPOptions property and set Enable = true.
• TsgcWebSocketServer_HTTPAPI: server component that supports HTTP/2 protocol (Microsoft implemen­
tation and Requires Windows 2016+ or Windows 10+).
• DataSnap Servers: datasnap server can support HTTP/2 protocol too.
 
 

APIs
• Apple Push Notifications: push user-facing notifications to the user's device from a server provider.
 
 
 

475
COMPONENTS

TsgcHTTP2Client
TsgcHTTP2Client implements Client HTTP/2 Component and can connect to a HTTP/2 Servers. Follow the next
steps to configure this component:
 
1. Create a new instance of TsgcHTTP2Client component.
 
2. Send the request to server and process the response using OnHTTP2Response event. example:
 

oClient := TsgcHTTP2Client.Create(nil);
oClient.OnHTTP2Response := OnHTTP2ResponseEvent;
oClient.Get('https://www.google.com');
 
procedure OnHTTP2ResponseEvent(Sender: TObject; const
    Connection: TsgcHTTP2ConnectionClient; const Request:
    TsgcHTTP2RequestProperty; const Response: TsgcHTTP2ResponseProperty);
begin
  ShowMessage(Response.DataString);
end;

Most common uses


• Requests
• Request HTTP/2 Method
• HTTP/2 Server Push
• Download File
• HTTP/2 Partial Responses
• HTTP/2 Headers
 
• Connection
• Client Close Connection
• Client Keep Connection Active
• HTTP/2 Reason Disconnection
• Client Pending Requests
 
• Authentication
• Client Authentication
• HTTP/2 and OAuth2
 
• Classes
• TsgcHTTP2ConnectionClient
• TsgcHTTP2RequestProperty
• TsgcHTTP2ResponseProperty
 
 

Methods
The following HTTP methods are supported:
 
    GET: The GET method requests a representation of the specified resource. Requests using GET should
only retrieve data.
 
    HEAD: The HEAD method asks for a response identical to that of a GET request, but without the re­
sponse body.
 
    POST: The POST method is used to submit an entity to the specified resource, often causing a change in
state or side effects on the server.

476
COMPONENTS

 
    PUT: The PUT method replaces all current representations of the target resource with the request pay­
load.
 
    DELETE: The HEAD method asks for a response identical to that of a GET request, but without the re­
sponse body.
 
    CONNECT: The CONNECT method establishes a tunnel to the server identified by the target resource.
 
    OPTIONS: The OPTIONS method is used to describe the communication options for the target resource.
 
    TRACE: The TRACE method performs a message loop-back test along the path to the target resource.
 
    PATCH: The PATCH method is used to apply partial modifications to a resource.
 
HTTP/2 client component also implement the following methods:
 
    Ping: sends a ping to a Server.
 
    Close: sends a message to server about connection will be closed.
 
    Disconnect: disconnects the socket connection.
 
 

Properties
    Authentication: allows to authenticate against OAuth2 before send an HTTP/2 request.
Token
OAuth: assign here a TsgcHTTP_OAuth_Client component to get OAuth2 credentials. Read more
about OAuth2.
JWT: assign here a TsgcHTTP_JWT_Client component to get JWT credentials. Read more about
JWT.
 
    Request: Specifies the header values to send to the HTTP/2 server.
 
    Settings: Specifies the header values to send to the HTTP/2 server.
 
EnablePush: by default enabled, this setting can be used to avoid server push content to client.
 
HeaderTableSize: Allows the sender to inform the remote endpoint of the maximum size of the header com­
pression table used to decode header blocks, in octets. The encoder can select any size equal to or less
than this value by using signaling specific to the header compression format inside a header block. The ini­
tial value is 4,096 octets.
 
InitialWindowSize: Indicates the sender’s  initial window size (in octets) for stream-level flow control. The
initial value is 65,535 octets. This setting affects the window size of all streams.
 
MaxConcurrentStreams: Indicates the maximum number of concurrent streams that the sender will allow.
This limit is directional: it applies to the number of streams that the sender permits the receiver to create. Ini­
tially, there is no limit to this value.
 
MaxFrameSize: Indicates the size of the largest frame payload that the sender is willing to receive, in
octets. The initial value is 16,384 octets.
 
MaxHeaderListSize: This advisory setting informs a peer of the maximum size of header list that the sender
is prepared to accept, in octets. The value is based on the uncompressed size of header fields, including the
length of the name and value in octets plus an overhead of 32 octets for each header field.
 
 
    Host: IP or DNS name of the server.
 
    HeartBeat: if enabled try to keeps alive HTTP/2 connection sending a ping every x seconds.
 

477
COMPONENTS

Interval: number of seconds between each ping.


 
    TCPKeepAlive: if enabled, uses keep-alive at TCP socket level, in Windows will enable SIO_KEEPALIVE_VALS
if supported and if not will use keepalive. By default is disabled. Read about Dropped Disconnections.
 
Time: if after X time socket doesn't sends anything, it will send a packet to keep-alive connection (value in
milliseconds).
 
Interval: after sends a keep-alive packet, if not received a response after interval, it will send another packet
(value in milliseconds).
 
    ConnectTimeout: max time in milliseconds before a connection is ready.
 
    ReadTimeout: max time in milliseconds to read messages.
 
    WriteTimeOut: max time in milliseconds sending data to other peer, 0 by default (only works under Windows
OS).
 
    Port: Port used to connect to the host.
 
    LogFile: if enabled save socket messages to a specified log file, useful for debugging. The access to log file is
not thread safe if it's accessed from several threads.
 
Enabled: if enabled every time a message is received and sent by socket it will be saved on a file.
 
FileName: full path to the filename.
 
    NotifyEvents: defines which mode to notify WebSocket events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 
    Proxy: here you can define if you want to connect through a HTTP Proxy Server. If you need to connect to
SOCKS proxies, just enable SOCKS.Enable property too.
 
    WatchDog: if enabled, when an unexpected disconnection is detected, tries to reconnect to the server automati­
cally.
 
Interval: seconds before reconnects.
 
Attempts: max number of reconnects, if zero, then unlimited.
 
    Throttle: used to limit the number of bits per second sent/received.
 
    TLS: enables a secure connection.
 
    TLSOptions: if TLS enabled, here you can customize some TLS properties.
 
ALPNProtocols: list of the ALPN protocols which will be sent to server.
RootCertFile: path to root certificate file.
CertFile: path to certificate file.
KeyFile: path to certificate key file.
Password: if certificate is secured with a password, set here.
VerifyCertificate: if certificate must be verified, enable this property.
VerifyDepth: is an Integer property that represents the maximum number of links permitted when verifica­
tion is performed for the X.509 certificate.
Version: by default uses TLS 1.0, if server requires a higher TLS version, here can be selected.
IOHandler: select which library you will use to connection using TLS.

478
COMPONENTS

iohOpenSSL: uses OpenSSL library and is the default for Indy components. Requires to deploy
openssl libraries for win32/win64.
iohSChannel: uses Secure Channel which is a security protocol implemented by Microsoft for Win­
dows, doesn't require to deploy openssl libraries. Only works in Windows 32/64 bits.
OpenSSL_Options: configuration of the openSSL libraries.
APIVersion: allows to define which OpenSSL API will be used.
oslAPI_1_0: uses API 1.0 OpenSSL, it's latest supported by Indy
oslAPI_1_1: uses API 1.1 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 1.1.1 libraries (with TLS 1.3 support).
oslAPI_3_0: uses API 3.0 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 3.0.0 libraries (with TLS 1.3 support).
LibPath: here you can configure where are located the openSSL libraries
oslpNone: this is the default, the openSSL libraries should be in the same folder where is the
binary or in a known path.
oslpDefaultFolder: sets automatically the openSSL path where the libraries should be located
for all IDE personalities.
oslpCustomFolder: if this is the option selected, define the full path in the property LibPath­
Custom.
LibPathCustom: when LibPath = oslpCustomFolder define here the full path where are located the
openSSL libraries.
UnixSymLinks: enable or disable the loading of SymLinks under Unix systems (by default is en­
abled, except under OSX64):
oslsSymLinksDefault: by default are enabled except under OSX64 (after MacOS Monterey
fails trying to load the library without version.).
oslsSymLinksLoadFirst: Load SymLinks and do before trying to load the version libraries.
oslsSymLinksLoad: Load SymLinks after trying to load the version libraries.
oslsSymLinksDontLoad: don't load the SymLinks.
SChannel_Options: allows to use a certificate from Windows Certificate Store.
CertHash: is the certificate Hash. You can find the certificate Hash running a dir command in power­
shell.
CipherList: here you can set which Ciphers will be used (separated by ":"). Example:
CALG_AES_256:CALG_AES_128
CertStoreName: the store name where is stored the certificate. Select one of below:
scsnMY (the default)
scsnCA
scsnRoot
scsnTrust
CertStorePath: the store path where is stored the certificate. Select one of below:
scspStoreCurrentUser (the default)
scspStoreLocalMachine
 
 

Events
    OnHTTP2Response
 
    This event is called when client receives a Response from Server. Access to Response object to get full informa­
tion about Server Response.
 
      Response.Headers: HTTP/2 headers
      Response.Data: Raw body response.
      Response.DataString: body response as string.
      Response.DataUTF8: body response as UTF-8 string.
 

procedure OnHTTP2ResponseEvent(Sender: TObject; const Connection: TsgcHTTP2ConnectionClient;


  const Request: TsgcHTTP2RequestProperty; const Response: TsgcHTTP2ResponseProperty);
begin
  ShowMessage(Response.Headers.Text + #13#10 + Response.DataString);
end;

 
    OnHTTP2ResponseFragment

479
COMPONENTS

 
    This event is called when client receives a fragment response from Server, so means that this stream will receive
more updates.
 
 
    OnHTTP2Authorization
 
    In this event you can set the UserName and Password when Authentication is Basic, or the Token for OAuth2
Authentications.
 
 
    OnHTTP2BeforeRequest
 
    This event is called before client sends Headers Request to server. You can add or modify the headers before
are sent to HTTP/2 server.
 
 
    OnHTTP2Connect
 
    This event is called just after client connects successfully to server.
 
 
    OnHTTP2Disconnect
 
    This event is called when connection is closed.
 
 
    OnHTTP2Exception
 
    If there is any exception while client is connected to server, here you can catch the Exception.
 
 
    OnHTTP2GoAway
 
    This event is raised when client receives a GoAway message from server.
 
 
    OnHTTP2PendingRequests
 
    After a disconnection, if there are pending requests to be sent or received, here you can set if you want recon­
nect and/or clear pending requests.
 
 
    OnHTTP2PushPromise
 
    When server sends a PushPromise to client, client can accept or not the PushPromise packets.
 
 
    OnHTTP2RSTStream
 
    When server resets a stream, this event is called.
 
 
 
 
 
 
 

480
COMPONENTS

TsgcHTTP2Client | Request HTTP/2 Method


HTTP/2 Client can work in blocking and non-blocking mode, internally the component works in a secondary thread
and requests are processed asynchronously, but you can call a request and wait till this request is completed.
 
Find below an example of how client can request an HTML page to a HTTP/2 Server and how can work in both
modes.

Asynchronous Mode
Get the following url: https://www.google.com and be notified when client receives the full response. After you call
GETASYNC method, the process continues and OnHTTP2Response event is called when response is received.
 

oClient := TsgcHTTP2Client.Create(nil);
oClient.OnHTTP2Response := OnHTTP2ResponseEvent;
oClient.GetAsync('https://www.gooogle.com');
procedure OnHTTP2ResponseEvent(Sender: TObject; const Connection: TsgcHTTP2ConnectionClient;
  const Request: TsgcHTTP2RequestProperty; const Response: TsgcHTTP2ResponseProperty);
begin
  ShowMessage(Response.Headers.Text + #13#10 + Response.DataString);
end;

Blocking Mode
Get the following url: https://www.google.com and wait till client receives the full response. After you call GET
method, the process waits till response is received or time out is reached.
You can access to the Raw Response data, using Response property of HTTP/2 client. Here you can access to
Raw Headers, Status response code, Charset and more.
 

oClient := TsgcHTTP2Client.Create(nil);
vResponse := oClient.Get('https://www.gooogle.com');
if oClient.Response.Status = 200 then
  ShowMessage('Response from server: ' + vResponse)
else
  ShowMessage('Response Code: ' + IntToStr(oClient.Response.Status));

481
COMPONENTS

Requests | HTTP/2 Server Push


Server Push is the ability of the server to send multiple responses for a single client request. That is, in addition to
the response to the original request, the server can push additional resources to the client, without the client having
to request each one explicitly.
 

 
Every time server sends to client a PushPromise message, OnHTTP2PushPromise event is called. When client re­
ceives a PushPromise, means that server will send in the next packets this resource, so client can accepts or not
this.
 

oClient := TsgcHTTP2Client.Create(nil);
oClient.OnHTTP2PushPromise := OnHTTP2PushPromiseEvent;
oClient.Get('https://http2.golang.org/serverpush');
...
procedure OnHTTP2PushPromiseEvent(Sender: TObject; const Connection: TsgcHTTP2ConnectionClient;
  const PushPromise: TsgcHTTP2_Frame_PushPromise; var Cancel: Boolean);
begin
  if PushPromise.URL = '/serverpush/static/godocs.js' then
    Cancel := True
  else
    Cancel := False;
end;

482
COMPONENTS

TsgcHTTP2Client | HTTP/2 Download File


When client request a file to server, use OnHTTP2Response event to load the stream response.
 

oClient := TsgcHTTP2Client.Create(nil);
oClient.OnHTTP2Response := OnHTTP2ResponseEvent;
oClient.Get('https://http2.golang.org/file/gopher.png');
...
procedure OnHTTP2ResponseEventEvent(Sender: TObject; const Connection: TsgcHTTP2ConnectionClient;
  const Request: TsgcHTTP2RequestProperty; const Response: TsgcHTTP2ResponseProperty)
begin
  oStream := TFileStream.Create('file', fmOpenWrite or fmCreate);
  Try
    oStream.CopyFrom(Response.Data, Response.Data.Size);
  Finally
    oStream.Free;
  End;
end;

483
COMPONENTS

TsgcHTTP2Client | HTTP/2 Partial Respons­
es
Usually when you send an HTTP Request, server sends a response with the file requested, sometimes, instead of
send a single response, server can send multiple response like a stream, in these cases you can use
OnHTTP2ResponseFragment event to capture these responses and show to user.
 
Example: send a request to https://http2.golang.org/clockstream and server will send a stream response every
second.
 

oClient := TsgcHTTP2Client.Create(nil);
oClient.OnHTTP2ResponseFragment := OnHTTP2ResponseFragmentEvent;
oClient.Get('https://http2.golang.org/clockstream');
...
procedure OnHTTP2ResponseFragmentEvent(Sender: TObject; const Connection: TsgcHTTP2ConnectionClient;
  const Request: TsgcHTTP2RequestProperty; const Fragment: TsgcHTTP2ResponseFragmentProperty);
begin
  ShowMessage(Fragment.DataString);
end;

484
COMPONENTS

TsgcHTTP2Client | HTTP/2 Headers


TsgcHTTP2Client allows to customize Headers sent to server when client connects  
Example: if you need to add this HTTP Header "Client: sgcWebSockets"

procedure OnHTTP2BeforeRequest(Sender: TObject; const Connection: TsgcHTTP2ConnectionClient;


  var Headers: TStringList);
begin
  Headers.Add('Client: sgcWebSockets');
end;

You can use Request.CustomHeaders to add your customized headers too.

485
COMPONENTS

TsgcHTTP2Client | Client Close Connection


Connection can be closed using Active property or using Close/Disconnect methods.
 

Active property
When connection is active and you set Active := False, the connection will be closed inmediately without sending
any message to server about the disconnection.
 

Disconnect
You can use Disconnect method (from TsgcHTTP2Client or TsgcHTTP2ConnectionClient) to disconnect the socket.

Close
This method, sends a message to server informing that connection will be closed and you can send optionally
some info about the reason of the disconnection. Is a clean mode of close a HTTP/2 connection.
Close method can be called from TsgcHTTP2Client or TsgcHTTP2ConnectionClient objects.
 
The following errors reasons can be send:
 
•   no error
•   protocol error
•   internal error
•   flow control error
•   settings timeout
•   stream closed
•   frame size error
•   refused stream
•   cancel
•   compression error
•   connect error
•   enhance your calm
•   inadequate security
•   required

486
COMPONENTS

TsgcHTTP2Client | Client Keep Connection


Active
Once your client has connected to server, sometimes connection can be closed due to poor signal, connection er­
rors... there are 2 properties which helps to keep connection active.
 

HeartBeat
HeartBeat property allows to send a Ping every X seconds to maintain connection alive. Some servers, close
TCP connections if there is no data exchanged between peers. HeartBeat solves this problem, sending a ping
every a specific interval. Usually this is enough to maintain a connection active.
 
Example: send a ping every 30 seconds

oClient := TsgcHTTP2Client.Create(nil);
oClient.HeartBeat.Interval := 30;
oClient.HeartBeat.Enabled := true;
oClient.Active := true;

WatchDog
If WatchDog is enabled, when client detects a disconnection, WatchDog try to reconnect again every X seconds
until connection is active again.
 
Example: reconnect every 10 seconds after a disconnection with unlimited attempts.
 

oClient := TsgcHTTP2Client.Create(nil);
oClient.WatchDog.Interval := 10;
oClient.WatchDog.Attempts := 0;
oClient.WatchDog.Enabled := true;
oClient.Active := true;

487
COMPONENTS

TsgcHTTP2Client | HTTP/2 Reason Discon­
nection
HTTP/2 Server can disconnect a client for several reasons, when server wants inform to client the reason why is
disconnecting, it sends a GoAway message to client with information about disconnection.
 
Use OnHTTP2GoAway event to catch the reason why server has disconnected (if client wants to close a connec­
tion, can use the method close to send the reason why is closing the connection).
 
TsgcHTTP2GoAwayProperty Object contains the information about disconnection
 
• LastStreamId: is the last stream processed by server.
• ErrorCode: integer which identifies the error code.
• ErrorDescription: description of the error, one of the following:
•   no error
•   protocol error
•   internal error
•   flow control error
•   settings timeout
•   stream closed
•   frame size error
•   refused stream
•   cancel
•   compression error
•   connect error
•   enhance your calm
•   inadequate security
•   required
• AdditionalDebugData: optional string which offers more information about disconnection.
 
 
  

488
COMPONENTS

TsgcHTTP2Client | Client Pending Requests


When client sends several requests, these are processed in a secondary thread, sometimes connection can be
closed for any reason, and there are still requests pending. Use OnHTTP2PendingRequests event to handle these
pending requests. This event is called when client detects a disconnection and there are still pending requests.
This event has 2 parameters:
 
1. Reconnect: by default disable, if you set to true, client will reconnect automatically.
2. Clear: by default enabled, if you set to false, when client connects again, it will try to resend pending requests to
server.

489
COMPONENTS

TsgcHTTP2Client | Client Authentication


HTTP/2 client supports 2 authentication types: Basic Authentication and OAuth2 Authentication.
 
Use OnHTTP2Authorization event to handle both types of authentication.
 

Basic Authentication
If server returns a header requesting Basic Authentication, set OnHTTP2Auithorization the username and pass­
word.
 

oClient := TsgcHTTP2Client.Create(nil);
oClient.OnHTTP2Authorization := OnHTTP2AuthorizationEvent;
...
procedure OnHTTP2AuthorizationEvent(Sender: TObject; const Connection: TsgcHTTP2ConnectionClient; const AuthType, AuthData:
begin
  if AuthType = 'Basic' then
  begin
    UserName := 'user';
Password := 'secret';
  end;
end;

Bearer Token
If server returns a header requesting Bearer Token Authentication, set OnHTTP2Authorization the token.
 

oClient := TsgcHTTP2Client.Create(nil);
oClient.OnHTTP2Authorization := OnHTTP2AuthorizationEvent;
...
procedure OnHTTP2AuthorizationEvent(Sender: TObject; const Connection: TsgcHTTP2ConnectionClient; const AuthType, AuthData:
begin
  if AuthType = 'Bearer' then
  begin
    aToken := 'bearer token';
  end;
end;

Bearer value from Third-party


If you already know the Bearer Value, because you have obtained using another method, you can pass the Bearer
value as an HTTP header using the following properties of the request, just set before calling any HTTP Request
method:
 

 
TsgcHTTP2Client.Request.BearerAuthentication
= true

TsgcHTTP2Client.Request.BearerToken = "< value of the token >"

OAuth2
Read the following article if you want to use our OAuth2 component with HTTP/2 client.

490
COMPONENTS

TsgcHTTP2Client | HTTP/2 and OAuth2


OAuth2 is a common authorization method uses by several companies like Google. When you want authenticate
against google servers to use any of their APIs, usually requires an Authentication using OAuth2.
 
sgcWebSockets supports OAuth2 under HTTP/2 client, there is a property called Authentication.Token.OAuth
where you must assign of TsgcHTTP_OAuth2.
 

How connect to GMail Google API


In order to connect to Google APIs, we will need to create an instance of TsgcHTTP_OAuth2 and fill the following
data:
 

TsgcHTTP_OAuth1.AuthorizationServerOptions.AuthURL := 'https://accounts.google.com/o/oauth2/auth';
TsgcHTTP_OAuth1.AuthorizationServerOptions.TokenURL := 'https://accounts.google.com/o/oauth2/token';

TsgcHTTP_OAuth1.LocalServerOptions.IP := '127.0.0.1';
TsgcHTTP_OAuth1.LocalServerOptions.Port := 8080;

TsgcHTTP_OAuth1.OAuth2Options.ClientId := 'your client id';


TsgcHTTP_OAuth1.OAuth2Options.ClientSecret := 'your client secret';

 
After fill the OAuth2 client component, create a new instance of TsgcHTTP2Client and Assign the OAuth2 compo­
nent to the HTTP/2 client.
 

 TsgcHTTP2Client1.Authentication.Token.OAuth := TsgcHTTP_OAuth1;

 
Finally, do a request to get a list of messages of account yourname@gmail.com
 

oStream := TStringStream.Create('');
Try
  TsgcHTTP2Client1.Get('https://gmail.googleapis.com/gmail/v1/users/yourname@gmail.com/messages', oStream);
  ShowMessage(oStream.DataString);
Finally
  oStream.Free;
End;

491
COMPONENTS

TsgcHTTP2ConnectionClient
TsgcHTTP2ConnectionClient is a wrapper of client HTTP/2 connections, you can access to this object on Client
Events.
 

Methods
• Ping: sends a ping to server to maintain connection alive.
• Close: sends a message to server with information about why is disconnecting.
• Disconnect: closes the connection without sending any informational message to then server.
• HTTP/2 Methods:
 
    GET: The GET method requests a representation of the specified resource. Requests using GET should
only retrieve data.
 
    HEAD: The HEAD method asks for a response identical to that of a GET request, but without the re­
sponse body.
 
    POST: The POST method is used to submit an entity to the specified resource, often causing a change in
state or side effects on the server.
 
    PUT: The PUT method replaces all current representations of the target resource with the request pay­
load.
 
    DELETE: The HEAD method asks for a response identical to that of a GET request, but without the re­
sponse body.
 
    CONNECT: The CONNECT method establishes a tunnel to the server identified by the target resource.
 
    OPTIONS: The OPTIONS method is used to describe the communication options for the target resource.
 
    TRACE: The TRACE method performs a message loop-back test along the path to the target resource.
 
    PATCH: The PATCH method is used to apply partial modifications to a resource.

492
COMPONENTS

TsgcHTTP2RequestProperty
This object is received as an argument OnHTTP2Response event, it allows to know the original request of the re­
sponse send by the server.
 

Properties
• Method: identifies the HTTP/2 method (GET, POST...)
• URL: is the URL requested.
• Request: contains the fields of the request.

493
COMPONENTS

TsgcHTTP2ResponseProperty
This object is received as an argument OnHTTP2Response event, it allows to know the response sent by the serv­
er to the client.
 

Properties
• Headers: contains a list of raw headers received from server.
• Data: contains the raw body sent by the server as response to request.
• DataString: is the conversion to string of Data.
• DataUTF8: is the conversion to UTF8 string of Data.
• PushPromise: if assigned, contains the PushPromise object sent by the server to client (means that this re­
sponse object has not been requested by client).
 

494
COMPONENTS

HTTP2 | Apple Push Notifications


https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server
 
Apple allow to send push notifications to apple devices using the Apple Push Notification Service (APNs).
 
When you want to send a notification to a device, the provider must send a HTTP/2 POST to APNs including the
following information:
 
• JSON Payload with the information you want to send.
• A Device Token that identifies the user's device.
• Some HTTP Headers about how deliver the notification.
• A SSL Certificate or a JWT Token to Authenticate your request against APNs

What's required to Send Notifications


In order to send notifications to your device using Rad Studio, you must follow the next steps
 
• Register your APP with APNs
• Generate a Remote Notification
• Sending Notification Requests to APNs
• Token-Based Connection to APNs
• Certificate-Based Connection to APNs

 
 
 
 
 
 

495
COMPONENTS

APN | Register your APP with APNs


https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns
 
You must know which is the device token which identifies the user's device where you want to send the notifica­
tions. This Device Token is unique for user and device.
 
To get the device token using Rad Studio follow the next steps:
 
1. Make use in your iOS Project of FMX.PushNotification.iOS and System.PushNotification units.
2. Use TPushServiceManager class to register your application and get the device token used.
 

var
  oPushService: TPushService;
  oPushConnection: TPushServiceConnection;
begin
  oPushService := TPushServiceManager.Instance.GetServiceByName(TPushService.TServiceNames.APS)
  oPushConnection := TPushServiceConnection.Create(oPushService);
  oPushConnection.Active := True;
  oPushConnection.OnChange := OnChangeEvent;
  oPushConnection.OnReceiveNotification := OnReceiveNotificationEvent;
  vDeviceId := oPushService.DeviceIDValue[TPushService.TDeviceIDNames.DeviceID];
  vDeviceToken := oPushService.DeviceTokenValue[TPushService.TDeviceTokenNames.DeviceToken];
end;

procedure OnChangeEvent(Sender: TObject; AChange: TPushService.TChanges);


begin
  memoLog.Lines.Add('OnChange');
end;

procedure OnReceiveNotificationEvent(Sender: TObject; const ANotification: TPushServiceNotifica


begin
  memoLog.Lines.Add('DataKey=' + ANotification.DataKey);
  memoLog.Lines.Add('JSON=' + ANotification.JSON.ToString);
  memoLog.Lines.Add('DataObject=' + ANotification.DataObject.ToString);
end;

The prior code basically creates a new connection with Apple Servers, when connection is fully established, returns
a device token that is the value used by sgcWebSockets service provider to send notifications to this user's de­
vice.

496
COMPONENTS

APN | Generate a Remote Notification APNs


https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/
generating_a_remote_notification
 
The Apple Notifications use a JSON payload to send the notification object. The maximum size of the payload is
4096 bytes.

JSON Payload Samples


Simple alert message

{
  "aps":{
    "alert":"Alert from sgcWebSockets!"
  }
}

Alert with title and subttile.

{
   "aps" : {
      "alert" : {
         "title" : "Game Request",
         "subtitle" : "Five Card Draw"
         "body" : "Bob wants to play poker",
      },
      "category" : "GAME_INVITATION"
   },
   "gameID" : "12345678"
}

497
COMPONENTS

APN | Sending Notification Requests to AP­
Ns
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server
 
Send your remote notification payload and device token information to Apple Push Notification service (APNs).
 

How Connect to APNs


You must use HTTP/2 protocol and at least TLS 1.2 or later to establish a successful connection between your
Server Provider and one of the following servers:
 
Development Server: https://api.sandbox.push.apple
Production Server: https://api.push.apple
 

Sample Code
Create a new instance of TsgcHTTP2Client and call the method POST to send a notification to APNs.
 

oHTTP := TsgcHTTP2Client.Create(nil);
Try
  // ... requires authorization code
  oStream := TStringStream.Create('{"aps":{"alert":"Alert from sgcWebSockets!"}}',
TEncoding.UTF8);
  Try
    oHTTP.Post('https://api.push.apple/3/device/device_token', oStream);
    if oHTTP.Response.Status = 200 then
      ShowMessage('Notification Sent Successfully')
    else
      ShowMessage('Notification error');
  Finally
    oStream.Free;
  End;
Finally
  oHTTP.Free;
End;

To send notifications, you must establish either token-based  or certificate-based trust with APNs using HTTP/2
protocol and TLS 1.2 or later.
 
• Token-Based Connection to APNs
• Certificate-Based Connection to APNs

498
COMPONENTS

APNs Trusted | Token-Based Connection to


APNs
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/
establishing_a_token-based_connection_to_apns
 
Secure your communications with Apple Push Notification service (APNs) by using stateless authentication Tokens.
 
First you must obtain an Encryption Key and a Key ID from Apple Developer Account. Once a successful registra­
tion, you will obtain a 10-Character string with the Key ID and an Authentication Token signing key as a .p8 file ex­
tension.
 
You must use the sgcWebSockets JWT Client to generate a JWT using ES256 as algorithm. The token must not be
generated for every HTTP/2 request, the token must not be refreshed before 20 minutes and not after 60 minutes.
 

Configure JWT Client


Configure the JWT Client with the following values:
 
• JWTOptions.Header.Algorithm: is the encryption algorithm you used to encrypt the token. APNs supports
only the ES256 algorithm.
• JWTOptions.Header.kid: is the 10-character Key ID obtained from your developer account.
• JWTOptions.Payload.iss: the value for which is the 10-character Team ID you use for developing your
company’s apps. Obtain this value from your developer account.
• JWTOptions.Payload.iat: The "issued at" time, whose value indicates the time at which this JSON token
was generated. Specify the value as the number of seconds since Epoch, in UTC. The value must be no
more than one hour from the current time.
• JWTOptions.RefreshTokenAfter: set the value in seconds to 40 minutes (60*40).
 
Using Token-Based connections, requires to send the apns-topic with the value of your app's bundle ID/app id (ex­
ample: com.example.application).

oHTTP := TsgcHTTP2Client.Create(nil);
oHTTP.TLSOptions.IOHandler := iohOpenSSL;

oJWT := TsgcHTTP_JWT_Client.Create(nil);
oHTTP.Authentication.Token.JWT := oJWT;
oJWT.JWTOptions.Header.alg := jwtES256;
oJWT.JWTOptions.Header.kid := 'apple key id';
oJWT.JWTOptions.Payload.iss := 'issuer';
oJWT.JWTOptions.Payload.iat := StrToInt64(GetDateTimeUnix(Now, False));
oJWT.JWTOptions.Algorithms.ES.PrivateKey.LoadFromFile('AuthKey_**.p8');
oJWT.JWTOptions.RefreshTokenAfter := 60*40;

oHTTP.Request.CustomHeaders.Clear;
oHTTP.Request.CustomHeaders.Add('apns-topic: com.example.application');

499
COMPONENTS

Certificate-Based Connection to APNs


https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/
establishing_a_certificate-based_connection_to_apns
 
You can secure your communications with Apple Push Notification service (APNs) using a certificate obtained from
Apple.
 

 
First enter in your developer account and create a new certificate for Apple Push Notification service
 
Once you have downloaded your certificate, the sgcWebSockets HTTP/2 client allows to use 2 security IOHandlers
(only for windows, for other personalities only openSSL is supported).
 
• OpenSSL
• SChannel (only for windows)
 

OpenSSL
If you use openSSL, you must deploy the openSSL libraries with your application. Before set the certificate with the
TsgcHTTP2Client, first this certificate must be converted to PEM format because openSSL doesn't allow to import
P12 certificates directly.
 
Use the following commands to convert a single P12 certificate to a certificate in PEM format and a private key file
 
create PEM certificate file

500
COMPONENTS

openssl pkcs12 -in INFILE.p12 -out OUTFILE.crt -nokeys

Create Private Key file

openssl pkcs12 -in INFILE.p12 -out OUTFILE.key -nodes -nocerts

Once you have your certificate and private key in PEM format, you can configure the TsgcHTTP2Client as follows.
 

oHTTP := TsgcHTTP2Client.Create(nil);
oHTTP.TLSOptions.IOHandler := iohOpenSSL;
oHTTP.TLSOptions.CertFile := 'certificate_file.pem';
oHTTP.TLSOptions.KeyFile := 'private_key.pem';
oHTTP.TLSOptions.Password := 'certificate password';
oHTTP.TLSOptions.Version := tls1_2;

SChannel
If you use SChannel there is no need to deploy any libraries and the certificate downloaded from Apple can be di­
rectly imported without the need of a previous conversion to PEM format.
 

oHTTP := TsgcHTTP2Client.Create(nil);
oHTTP.TLSOptions.IOHandler := iohSChannel;
oHTTP.TLSOptions.CertFile := 'certificate_file.p12';
oHTTP.TLSOptions.Password := 'certificate password';
oHTTP.TLSOptions.Version := tls1_2;

Errors
If you get the error "missing topic" most probably you are using an universal certificate (certificates that can be
used for push notifications, voip...) which requires to set the topic name with the value of your app's bundle ID/app
id (example: com.example.application). Just set the apns-topic header with the correct value in the Request proper­
ty of the HTTP/2 client.
 

oHTTP.Request.CustomHeaders.Clear;
oHTTP.Request.CustomHeaders.Add('apns-topic: com.example.application');

501
COMPONENTS

HTTP/1
TsgcHTTP1Client is a non-visual component that inherits from TIdHTTP indy component and adds some new
properties.
This component is located in sgcHTTP unit.

TLSOptions
Allows to configure how connect to secure SSL/TLS servers using HTTP/1 protocol
 
ALPNProtocols: list of the ALPN protocols which will be sent to server.
RootCertFile: path to root certificate file.
CertFile: path to certificate file.
KeyFile: path to certificate key file.
Password: if certificate is secured with a password, set here.
VerifyCertificate: if certificate must be verified, enable this property.
VerifyDepth: is an Integer property that represents the maximum number of links permitted when verifica­
tion is performed for the X.509 certificate.
Version: by default uses TLS 1.0, if server requires a higher TLS version, here can be selected.
IOHandler: select which library you will use to connection using TLS.
iohOpenSSL: uses OpenSSL library and is the default for Indy components. Requires to deploy
openssl libraries for win32/win64.
iohSChannel: uses Secure Channel which is a security protocol implemented by Microsoft for Win­
dows, doesn't require to deploy openssl libraries. Only works in Windows 32/64 bits.
OpenSSL_Options: configuration of the openSSL libraries.
APIVersion: allows to define which OpenSSL API will be used.
oslAPI_1_0: uses API 1.0 OpenSSL, it's latest supported by Indy
oslAPI_1_1: uses API 1.1 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 1.1.1 libraries (with TLS 1.3 support).
oslAPI_3_0: uses API 3.0 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 3.0.0 libraries (with TLS 1.3 support).
LibPath: here you can configure where are located the openSSL libraries
oslpNone: this is the default, the openSSL libraries should be in the same folder where is the
binary or in a known path.
oslpDefaultFolder: sets automatically the openSSL path where the libraries should be located
for all IDE personalities.
oslpCustomFolder: if this is the option selected, define the full path in the property LibPath­
Custom.
LibPathCustom: when LibPath = oslpCustomFolder define here the full path where are located the
openSSL libraries.
UnixSymLinks: enable or disable the loading of SymLinks under Unix systems (by default is en­
abled, except under OSX64):
oslsSymLinksDefault: by default are enabled except under OSX64 (after MacOS Monterey
fails trying to load the library without version.).
oslsSymLinksLoadFirst: Load SymLinks and do before trying to load the version libraries.
oslsSymLinksLoad: Load SymLinks after trying to load the version libraries.
oslsSymLinksDontLoad: don't load the SymLinks.
SChannel_Options: allows to use a certificate from Windows Certificate Store.
CertHash: is the certificate Hash. You can find the certificate Hash running a dir command in power­
shell.
CipherList: here you can set which Ciphers will be used (separated by ":"). Example:
CALG_AES_256:CALG_AES_128
CertStoreName: the store name where is stored the certificate. Select one of below:
scsnMY (the default)
scsnCA
scsnRoot
scsnTrust
CertStorePath: the store path where is stored the certificate. Select one of below:
scspStoreCurrentUser (the default)
scspStoreLocalMachine

502
COMPONENTS

Log
If Log property is enabled it saves socket messages to a specified log file, useful for debugging.
 
LogOptions.FileName: full path to the filename.
 

Authentication
Allows to Authenticate using OAuth2 or JWT.
 

Examples
Request a GET method to HTTPs server and using TLS 1.2

oHTTP := TsgcHTTP1Client.Create(nil);
Try
  oHTTP.TLSOptions.Version := tls1_2;
  ShowMessage(oHTTP.Get('https://www.google.es'));
Finally
  oHTTP.Free;
End;

Request a GET method to HTTPs server using openSSL 1.1 and TLS 1.3

oHTTP := TsgcHTTP1Client.Create(nil);
Try
  oHTTP.TLSOptions.OpenSSL_Options.APIVersion := oslAPI_1_1;
  oHTTP.TLSOptions.Version := tls1_3;
  ShowMessage(oHTTP.Get('https://www.google.es'));
Finally
  oHTTP.Free;
End;

Request a GET method to HTTPs server using SChannel for Windows.

oHTTP := TsgcHTTP1Client.Create(nil);
Try
  oHTTP.TLSOptions.IOHandler := iohSChannel;
  oHTTP.TLSOptions.Version := tls1_2;
  ShowMessage(oHTTP.Get('https://www.google.es'));
Finally
  oHTTP.Free;
End;

503
COMPONENTS

HTTP | OAuth2
OAuth2 allows third-party applications to receive a limited access to an HTTP service which is either on behalf of a
resource owner or by allowing a third-party application obtain access on its own behalf. Thanks to OAuth2, service
providers and consumer applications can interact with each other in a secure way.
 
In OAuth2, there are 4 roles:
 
• Resource Owner: the user.
• Resource Server: the server that hosts the protected resources and provides access to it based on the ac­
cess token.
• Client: the external application that seeks permission.
• Authorization Server: issues the access token after having authenticated the user.
 
 

Components
• TsgcHTTP_OAuth2_Client: is a client with support for OAuth2, so it can connect to OAuth2 servers to re­
quest an authentication like Google, Facebook...
• TsgcHTTP_OAuth2_Server: is the server implementation of OAuth2 protocol.
 

504
COMPONENTS

OAuth2 | TsgcHTTP_OAuth2_Client
This component allows to handle flow between client and the other roles, basically, when you set Active := True,
opens a new Web Browser and requests user grant authorization, if successful, authorization server sends a token
to application which is processed and with this token, client can connect to resource server. This component, starts
a simple HTTP server which handles authorization server responses and uses an HTTP client to request Access
Tokens.
 
GrantType
 
Client supports 2 types of Authorization:
 
auth2Code: It's used to perform authentication and authorization in the majority of application types, including sin­
gle page applications, web applications, and natively installed applications. The flow enables apps to securely ac­
quire access_tokens that can be used to access resources secured, as well as refresh tokens to get additional
access_tokens, and ID tokens for the signed in user.
 

 
auth2ClientCredentials: This type of grant is commonly used for server-to-server interactions that must run in the
background, without immediate interaction with a user. These types of applications are often referred to as dae­
mons or service accounts.
 

505
COMPONENTS

 
LocalServerOptions
 
When a client needs a new Access Token, automatically starts an HTTP server to process response from Autho­
rization server. This server is transparent for user and usually works in localhost. By default uses port 8080 but you
can change if needed.
 
• IP: IP server listening, example: 127.0.0.1
• Port: by default 8080
• RedirectURL: (optional) allows to customized redirect url, example: http://localhost:8080/oauth/.
• SSL: enable this property if local server runs on a secure port (*only supported by Professional and Enter­
prise Editions).
• SSLOptions: allows to customize the SSL properties of server (*only supported by Professional and Enter­
prise Editions).
 
AuthorizationServerOptions
 
Here you must set URL for Authorization and Acces Token, usually these are provided in API specification. Scope
is a list of all scopes requested by client. Example:
 
• AuthURL: https://accounts.google.com/o/oauth2/auth
• TokenURL: https://accounts.google.com/o/oauth2/token
• Scope: https://mail.google.com/
• EncodeScope: if true, encodes the scope string as PathEncode (by default true).
 
OAuth2Options
 
ClientId is a mandatory field which informs server which is the identification of client. Check your API specification
to know how get a ClientId. The same applies for client secret.
Sometimes, server requires a user and password to connect using Basic Authentication, if this is the case, you can
setup this in Username/Password fields. Example:
 
• ClientId: 180803918307-eqjtm20gqfhcs6gjklbbrreng022mqqc.apps.googleusercontent.com
• ClientSecret: _by1iYYrvVHxC2Z8TbtNEYJN
• Username:
• Password:
 
HTTPClientOptions
 
Here you can customize the Client Options when connects to HTTP Server to request a new token.
 

506
COMPONENTS

    TLSOptions: if TLS enabled, here you can customize some TLS properties.
 
ALPNProtocols: list of the ALPN protocols which will be sent to server.
RootCertFile: path to root certificate file.
CertFile: path to certificate file.
KeyFile: path to certificate key file.
Password: if certificate is secured with a password, set here.
VerifyCertificate: if certificate must be verified, enable this property.
VerifyDepth: is an Integer property that represents the maximum number of links permitted when verifica­
tion is performed for the X.509 certificate.
Version: by default uses TLS 1.0, if server requires a higher TLS version, here can be selected.
IOHandler: select which library you will use to connection using TLS.
iohOpenSSL: uses OpenSSL library and is the default for Indy components. Requires to deploy
openssl libraries for win32/win64.
iohSChannel: uses Secure Channel which is a security protocol implemented by Microsoft for Win­
dows, doesn't require to deploy openssl libraries. Only works in Windows 32/64 bits.
OpenSSL_Options: allows to define which OpenSSL API will be used.
APIVersion: allows to define which OpenSSL API will be used.
oslAPI_1_0: uses API 1.0 OpenSSL, it's latest supported by Indy
oslAPI_1_1: uses API 1.1 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 1.1.1 libraries (with TLS 1.3 support).
oslAPI_3_0: uses API 3.0 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 3.0.0 libraries (with TLS 1.3 support).
LibPath: here you can configure where are located the openSSL libraries
oslpNone: this is the default, the openSSL libraries should be in the same folder where is the
binary or in a known path.
oslpDefaultFolder: sets automatically the openSSL path where the libraries should be located
for all IDE personalities.
oslpCustomFolder: if this is the option selected, define the full path in the property LibPath­
Custom.
LibPathCustom: when LibPath = oslpCustomFolder define here the full path where are located the
openSSL libraries.
UnixSymLinks: enable or disable the loading of SymLinks under Unix systems (by default is en­
abled, except under OSX64):
oslsSymLinksDefault: by default are enabled except under OSX64 (after MacOS Monterey
fails trying to load the library without version.).
oslsSymLinksLoadFirst: Load SymLinks and do before trying to load the version libraries.
oslsSymLinksLoad: Load SymLinks after trying to load the version libraries.
oslsSymLinksDontLoad: don't load the SymLinks.
SChannel_Options: allows to use a certificate from Windows Certificate Store.
CertHash: is the certificate Hash. You can find the certificate Hash running a dir command in power­
shell.
CertStoreName: the store name where is stored the certificate. Select one of below:
scsnMY (the default)
scsnCA
scsnRoot
scsnTrust
CertStorePath: the store path where is stored the certificate. Select one of below:
scspStoreCurrentUser (the default)
scspStoreLocalMachine
 
    LogOptions: if a filename is set, it will save a log of HTTP requests/responses.
 
 

OnBeforeAuthorizeCode

This is the first event, it's called before client opens a new Web Browser session. URL parameter can be modified if
needed (usually not necessary).

procedure OnOAuth2BeforeAuthorizeCode(Sender: TObject; var URL: string; var Handled:


Boolean);
begin

507
COMPONENTS

  DoLog('BeforeAuthorizeCode: ' + URL);


end;

OnAfterAuthorizeCode

After a successful Authorization, server redirects the response to internal HTTP server, this response informs to
client about Authorization code (which will be use later to get Access Token), state, scope...

procedure OnOAuth2AfterAuthorizeCode(Sender: TObject; const Code, State, Scope, RawParams: string;


  var Handled: Boolean);
begin
  DoLog('AfterAuthorizeCode: ' + Code);
end;

OnErrorAuthorizeCode

If there is an error, this event will be raised with information about error.

procedure OnOAuth2ErrorAuthorizeCode(Sender: TObject; const Error, Error_Description, Error_URI, State,


  RawParams: string);
begin
  DoLog('ErrorAuthorizeCode: ' + Error + ' ' + Error_Description);
end;

OnBeforeAccessToken

After get an Authorization Code, client connects to Authorization Server to request a new Access Token. Before
client connects, this event is called where you can modify URL and parameters (usually not needed).

procedure OnOAuth2BeforeAccessToken(Sender: TObject; var URL, Parameters: string;


  var Handled: Boolean);
begin
  DoLog('BeforeAccesToken: ' + URL + ' ' + Parameters);
end;

OnAfterAccessToken

If server accepts client requests, it releases a new Access Token which will be used by client to get access to re­
sources server.

procedure OnOAuth2AfterAccessToken(Sender: TObject; const Access_Token, Token_Type, Expires_In,


  Refresh_Token, Scope, RawParams:
    string; var Handled: Boolean);
begin
  DoLog('AfterAccessToken: ' + Access_Token + ' ' + Refresh_Token + ' ' + Expires_In);
end;

OnErrorAccessToken

If there is an error, this event will be raised with information about error.

procedure OnOAuth2ErrorAccessToken(Sender: TObject; const Error, Error_Description, Error_URI,


  RawParams: string);
begin
  DoLog('ErrorAccessToken: ' + Error + ' ' + Error_Description);
end;

508
COMPONENTS

OnBeforeRefreshToken

Access token expire after some certain time. If Authorization server releases a refresh token plus access token,
client can connect after token has expires with a refresh token to request a new access token without the need of
user Authenticates again with own credentials. This event is called before client requests a new access token.

procedure ONOAuth2BeforeRefreshToken(Sender: TObject; var URL, Parameters: string; var Handled: Boolean);
begin
  DoLog('BeforeRefreshToken: ' + URL + ' ' + Parameters);
end;

OnAfterRefreshToken

If server accepts client requests, it releases a new Access Token which will be used by client to get access to re­
sources server.

procedure OnOAuth2AfterRefreshToken(Sender: TObject; const Access_Token, Token_Type, Expires_In,


  Refresh_Token, Scope, RawParams: string; var Handled: Boolean);
begin
  DoLog('AfterRefreshToken: ' + Access_Token + ' ' + Refresh_Token + ' ' + Expires_In);
end;

OnErrorRefreshToken

If there is an error, this event will be raised with information about error.

procedure OnOAuth2ErrorRefreshToken(Sender: TObject; const Error, Error_Description, Error_URI,


  RawParams: string);
begin
  DoLog('ErrorRefreshToken: ' + Error + ' ' + Error_Description);
end;

OnHTTPResponse

This event is called before HTTP response is sent after a successful Access Token.

procedure OnOAuth2HTTPResponse(Sender: TObject; var Code: Integer; var Text: string; var Handled: Boolean);
begin
  Code := 200;
  Text := 'Successful Authorization';
end;

OAuth2 Code Example


Example of use to connect to Google Gmail API using OAuth2.  

oAuth2 := TsgcHTTP2_OAuth2.Create(nil);
oAuth2.LocalServerOptions.Host := '127.0.0.1';
oAuth2.LocalServerOptions.Port := 8080;
oAuth2.AuthorizationServerOptions.AuthURL := 'https://accounts.google.com/o/oauth2/auth';
oAuth2.AuthorizationServerOptions.Scope.Add('https://mail.google.com/');
oAuth2.AuthorizationServerOptions.TokenURL := 'https://accounts.google.com/o/oauth2/token';
oAuth2.OAuth2Options.ClientId := '180803918357-eqjtn20gqfhcs6gjkebbrrenh022mqqc.apps.googleusercontent.com';
oAuth2.OAuth2Options.ClientSecret := '_by0iYYrvVHxC2Z8TbtNEYQN';

  
procedure OnOAuth2AfterAccessToken(Sender: TObject; const Access_Token, Token_Type, Expires_In,
  Refresh_Token, Scope, RawParams: string; var Handled: Boolean);
begin
  <...>

  
  <...>
end;

509
COMPONENTS

oAuth2.OnAfterAccessToken := OnOAuth2AfterAccessToken;
oAuth2.Start;

510
COMPONENTS

OAuth2 | TsgcHTTP_OAuth2_Server
This component provides the OAuth2 protocol implementation in Server Side Components.
 
The server components have a property called Authorization.OAuth.OAuth2 where you can assign an instance of
TsgcHTTP_OAuth2_Server, so if Authentication is enabled and OAuh2 property is attached to OAuth2 Server Com­
ponent, the WebSocket and HTTP Requests require a Bearer Token to be processed, if not the connection will be
closed automatically.

OAuth2 := TsgcHTTP_OAuth2_Server.Create(nil);
Server.Authentication.Enabled := True;
Server.Authentication.OAuth.OAuth2 := OAuth2;

EndPoints
By default, the component is configured with the following endpoints to handle Authorization and Token request
 
Authorization: /sgc/oauth2/auth
Token: /sgc/oauth2/token
 
So if server is listening on port 443 and domain is www.esegece.com, the EndPoints will be:
 
Authorization: https://www.esegece.com/sgc/oauth2/auth
Token: https://www.esegece.com/sgc/oauth2/token
 
The endpoints can be configured in OAuth2Options property.
 

Configuration
Before you can begin the OAuth2 process, you must register which Apps will be available, this is done using Apps
property of OAuth2 server component.

Register App

Use Apps.AddApp to add a new Application to OAuth2 server, you must set the following parameters:
 
• App Name: is the name of the Application. Example: MyApp
• RedirectURI: is where the responses will be redirected. Example: http://127.0.0.1:8080
• ClientId: is public information and is the ID of the client.
• ClientSecret: must be kept confidential.
 
Optionally you can set the following parameters:
 
• ExpiresIn: by default is 3600 seconds, so the token will expire in 1 hour, you can set a greater value if you
need.
• RefreshToken: by default refresh tokens are supported, if not, set this parameter to false.

Delete App

Use Apps.RemoveApp to delete an existing App.


 

511
COMPONENTS

AddToken

If the server has been restarted while there were some token issued, you can recover these tokens using the
method AddToken before starting the OAuth2 Server and after registering the Apps
 
• AppName: the name of the application.
• Token: access token.
• Expires: when the token expires.
• RefreshToken: refresh token.
 

RemoveToken

Removes an already issued Token.


 
 

Most common uses


• QuickStart
• OAuth2 Server Example
• OAuth2 Customize Sign-in HTML
• OAuth2 Server Endpoints
• OAuth2 Register Apps
• OAuth2 Recover Access Tokens
 
• Authenticate
• OAuth2 Server Autentication
• OAuth2 None Authenticate some URLs
 

Connections
While OAuth2 is enabled on Server-side, if a websocket client tries to connect without providing a valid Token, the
connection will be closed automatically. The same applies to HTTP requests.
 
TsgcWebSocketClient can be configured to request a OAuth2 token and sent when connects to server. You have 2
options in order to send a Bearer Token:
 
1. Use Authentication.Token property, this is usefull when you have a valid token obtained from an external third-
party and you only want to pass as a connection header to get Access to server.

Authorization.Enabled := True;
Authorization.Token.Enabled := True;
Authorization.Token.AuthName := 'Bearer';
Authorization.Token.AuthToken := 'your token here';

2. Attach a TsgcHTTP_OAuth2_Client and let the client request an Access Token and send it automatically when
websocket client connects to server.

Events
Some events are provided to handle the OAuth2 Flow Control.
 

512
COMPONENTS

OnOAuth2BeforeRequest

This event is called when a new HTTP connection is established with server and before checks if the connection
request is trying to do an Authorization or request a new token. If you don't need that this request is processed by
OAuth2 server, set Cancel parameter to true.
 
The event is called too when checks if the Token is valid.
 

OnOAuth2BeforeDispatchPage
The event is called before the Authorization web-page is showed to user, allows to customize the HTML code
shown to user.
 

OnOAuth2Authentication
When a client request Authorization, server shows a page were user can allow connection and requires to login to
server. This is the event where you can read the User/Password set by user and accept or not the connection.
 

OnOAuth2AfterAccessToken
After the server process successfully the Access Token, this event is called. Useful for log purposes.
 

OnOAuth2AfterRefreshToken
After the server process successfully the Refresh Token, this event is called. Useful for log purposes.
 

OnOAuth2AfterValidateAccessToken
When a client do a request with a Token, this token is processed by server to check if it's valid or not, if the token is
valid and not expired, this event is called. Useful for log purposes.

513
COMPONENTS

OAuth2 | Server Example


Let's do a simple OAuth2 server example, using a TsgcWebSocketHTTPServer.
 
First, create a new TsgcWebSocketHTTPServer listening on port 443 and using a self-signed certificate in sgc.pem
file.

oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 80;
oServer.SSLOptions.Port := 443;
oServer.SSLOptions.CertFile := 'sgc.pem';
oServer.SSLOptions.KeyFile := 'sgc.pem';
oServer.SSLOptions.RootCertFile := 'sgc.pem';
oServer.SSL := True;

Then create a new instance of TsgcHTTP_OAuth2_Server and assign to previously created server.
Register a new Application with the following values:
 
Name: MyApp
RedirectURI: http://127.0.0.1:8080
ClientId: client-id
ClientSecret: client-secret
 

OAuth2 := TsgcHTTP_OAuth2_Server.Create(nil);
OAuth2.Apps.AddApp('MyApp', 'http://127.0.0.1:8080', 'client-id', 'client-secret');
oServer.Authentication.Enabled := True;
oServer.Authentication.OAuth.OAuth2 := OAuth2;

Then handle OnOAuth2Authentication event of OAuth2 server component and implement your own method to login
users. I will use the pair "user/secret" to accept a login.

procedure OnAuth2Authentication(Connection: TsgcWSConnection; OAuth2: TsgcHTTPOAuth2Request; aUser,


  aPassword: string; var Authenticated: Boolean);
begin
  if ((aUser = 'user') and (aPassword = 'secret')) then
    Authenticated := True;
end;

Finally start the server and use a OAuth2 client to login, example you can use the TsgcHTTP_OAuth2_Client  in­
cluded with sgcWebSockets library.
 

514
COMPONENTS

 
Request a New Access Token, a new Web Browser session will be shown and user must Allow connection and
then login.
 

515
COMPONENTS

 
If login is successful a new Token will be returned to the client. Then all the requests must include this bearer token
in the HTTP Headers.
 

516
COMPONENTS

517
COMPONENTS

OAuth2 | Customize Sign-In HTML


When an OAuth2 client do a request to get a new Access Token, a Web-Page is shown in a web-browser to Allow
this connection and login with an User and Password.
The HTML page is included by default in Server component, but this code can be customized using
OnAuth2BeforeDispatchPage event.
 

procedure OnOAuth2BeforeDispatchPage(Sender: TObject; OAuth2: TsgcHTTPOAuth2Request; var HTML: string);


begin
  HTML := 'your custom html';
end;

If you customize your HTML with a completely new HTML code, at least you must maintain the form where the
Username and password are sent:
 
<form action="">
<input type="hidden" name="request_type" value="sign-in" />
<input type="username" name="username" placeholder="Username" />
<input type="password" name="password" placeholder="Password" />
<input type="hidden" name="id" value="" />
<p></p>
<button>Sign In</button>
</form>
 
The id parameter, which is hidden, must maintain the same value of the original form to allow server identify the re­
quest.

518
COMPONENTS

OAuth2 | Server Endpoints


By default, the OAuth2 Server uses the following Endpoints:
 
Authorization: /sgc/oauth2/auth
Token: /sgc/oauth2/token
 
Which means that if your server listens on IP 80.54.41.30 and port 8443, the full OAuth2 Endpoints will be:
 
Authorization: https://80.54.41.30:8443/sgc/oauth2/auth
Token: https://80.54.41.30:8443/sgc/oauth2/token
 
This Endpoints can be modified easily, just access to OAuth2Options property of component and modify Authoriza­
tion and Token URLs.
Example: if your endpoints must be
 
Authorization: https://80.54.41.30:8443/authentication/auth
Token: https://80.54.41.30:8443/authentication/token
 
Set the OAuth2Options property with the following values:
 
OAuth2Options.Authorization.URL = /authentication/auth
OAuth2Options.Token.URL = /authentication/token
 

519
COMPONENTS

OAuth2 | Register Apps


Before a new OAuth2 is requested by a client, the App must be registered in the server.
Register a new App requires the following information:
 
• App Name: is the name of the Application. Example: MyApp
• RedirectURI: is where the responses will be redirected. Example: http://127.0.0.1:8080
• ClientId: is public information and is the ID of the client.
• ClientSecret: must be kept confidential.
 
Optionally you can set the following parameters:
 
• ExpiresIn: by default is 3600 seconds, so the token will expire in 1 hour, you can set a greater value if you
need.
• RefreshToken: by default refresh tokens are supported, if not, set this parameter to false.
 
 
If a new client wants to authenticate using OAuth2, first the App requires to be registered in the server, you can
use:
 
1. RegisterApp
This method requires the App Name and RedirectURI, and will return a ClientId and ClientSecret.
 
2. Apps.AddApp
This method requires AppName, RedirectURI, ClientId and ClientSecret. Usually you can use this method when a
server has some already created Apps and you want to load them before is started.
 
Both methods do the same, register the Application in the server, but first is most useful when the App is registered
the first time and second method when you want to load all registered apps before start the server (because are
saved on database for example).
 
 

520
COMPONENTS

OAuth2 | Recover Access Tokens


If the OAuth2 Server is destroyed (because it's restarted) and there are valid Access Tokens issued, these are lost
by default. You can recover these Access Tokens using the method AddToken. This method stores the tokens in
the OAuth2 Server.
 
Add a Token requires the following information:
 
• AppName: the name of the app.
• Token: access token.
• Expires: when the token expires.
• RefreshToken: refresh token.
 
You can save the issued tokens handling the OAuth2AfterAccessToken event.
 

procedure OnOAuth2AfterAccessToken(Sender: TObject; Connection: TsgcWSConnection; OAuth2: TsgcHTTPOAuth2Request;


  aResponse: string);
begin
  // ... store OAuth2 Token data
end;

OAuth2 := TsgcHTTP_OAuth2_Server.Create(nil);
OAuth2.Apps.AddApp('MyApp', 'http://127.0.0.1:8080', 'client-id', 'client-secret');
OAuth2.AddToken('MyApp', '12146ce12b0e4813987f2794f768905cefc39da6fbd54f6d9b38387489280608', EncodeDate(2022,1,1),
  'ef3e3dfa56ec44109c3d345b1541f08e539ce21432d9433099b48a3d08d34bc0');
oServer.Authentication.Enabled := True;
oServer.Authentication.OAuth.OAuth2 := OAuth2;

521
COMPONENTS

OAuth2 | Server Authentication


When an OAuth2 client requests a new Authorization, the server shows a web page where the user must allow the
connection and then login. This page is provided by sgcWebSockets library and is dispatched automatically when a
client requests an Authorization.
 

 
If the user Allows the access, a login form will be shown where the user must set the Username and Password.
This data will be received OnOAuth2Authentication event, so you must validate than the user/password is correct
and if it is, then set Authenticated parameter to true.
 

procedure OnAuth2Authentication(Connection: TsgcWSConnection; OAuth2: TsgcHTTPOAuth2Request; aUser,


  aPassword: string; var Authenticated: Boolean);
begin
  if ((aUser = 'user') and (aPassword = 'secret')) then
    Authenticated := True;
end;

522
COMPONENTS

OAuth2 | None Authenticate URLs


By default, when OAuth2 is enabled on Server Side, all the HTTP Requests require Authentication using Bearer To­
kens.
If you want allow some URLs to be accessed without the need of use a Bearer Token, you can use the event
OnOAuth2BeforeRequest
 

procedure OnOAuth2BeforeRequest(Sender: TObject; aConnection: TsgcWSConnection; aHeaders: TStringList;


  var Cancel: Boolean);
begin
  if DecodeGETFullPath(aHeaders) = '/Public.html' then
    Cancel := True
  else if DecodePOSTFullPath(aHeaders) = '/Form.html' then
    Cancel := True;  
end;

523
COMPONENTS

HTTP | JWT
JWT (JSON Web Token) typically consists of a header + payload + signature.
 
Header
 
Contains the metadata information about JWT
 
• alg: is the algorithm used to sign the token
• typ: is the type of the token, always JWT

{
  "alg": "HS256",
  "typ": "JWT"
}

You can find more headers but the previous will be always there.
 
Payload
 
The payload contains the claims of the JWT. The standard headers are the following:
 
• iss: is the issuer, the entity who generates and issue the JWT.
• sub: is the subject, the entity identified by this token.
• aud: is the audience, the target audience for this JWT.
• exp: is the expiry, is the timestamp in UNIX format after the token should not be accepted.
• iat: is issued at, specifies the date when the token has been issued.

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

 
Signature
 
The signature is created using the Encoded Header, Encoded Payload, a Secret and a Cryptographic Algorithm.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0

NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5M

DIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Algorithms supported
The following algorithms are supported by both Client and Server JWT components.
 
• HS256
• HS384
• HS512
• RS256
• RS384
• RS512
• ES256
• ES384
• ES512
 

524
COMPONENTS

OpenSSL libraries are required to sign and verify the JWT.

Components
 
• TsgcHTTP_JWT_Client: JWT client which allows to encode and sign JWT and send as an Authorization
Header in HTTP and WebSocket protocols.
• TsgcHTTP_JWT_Server: JWT server which allows to decode and validate JWT received as an Authoriza­
tion Header in HTTP and WebSocket protocols.
 
 
* JWT Components require at least Indy version 10.6.0.5169 or sgcWebSockets Enterprise Edition.

525
COMPONENTS

JWT | TsgcHTTP_JWT_Client
The TsgcHTTP_JWT_Client component allows to encode and sign JWT Tokens, attached to a WebSocket Client or
HTTP/2 client, the token will be sent automatically as an Authorization Bearer Token Header.

Configuration
You can configure the JWT values in the JWTOptions properties, there are 2 main properties: Header and Pay­
load, just set the values for every required property.
 
If the Signature is encrypted using a Private Key (RS and ES algorithms), set the value in the PrivateKey property
of the Algorithm.
If the Signature is encrypted using a Secret (HS algorithms), set the value in the Secret property of the Algorithm.
 

OpenSSL Options
Configure which openSSL libraries you will use when using JWT client.
 
OpenSSL_Options: configuration of the openSSL libraries.
APIVersion: allows to define which OpenSSL API will be used.
oslAPI_1_0: uses API 1.0 OpenSSL, it's latest supported by Indy
oslAPI_1_1: uses API 1.1 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 1.1.1 libraries (with TLS 1.3 support).
oslAPI_3_0: uses API 3.0 OpenSSL, requires our custom Indy library and allows to use
OpenSSL 3.0.0 libraries (with TLS 1.3 support).
LibPath: here you can configure where are located the openSSL libraries
oslpNone: this is the default, the openSSL libraries should be in the same folder where is the
binary or in a known path.
oslpDefaultFolder: sets automatically the openSSL path where the libraries should be located
for all IDE personalities.
oslpCustomFolder: if this is the option selected, define the full path in the property LibPath­
Custom.
LibPathCustom: when LibPath = oslpCustomFolder define here the full path where are located the
openSSL libraries.
UnixSymLinks: enable or disable the loading of SymLinks under Unix systems (by default is en­
abled, except under OSX64):
oslsSymLinksDefault: by default are enabled except under OSX64 (after MacOS Monterey
fails trying to load the library without version.).
oslsSymLinksLoadFirst: Load SymLinks and do before trying to load the version libraries.
oslsSymLinksLoad: Load SymLinks after trying to load the version libraries.
oslsSymLinksDontLoad: don't load the SymLinks.
 

Custom Headers
The Header and Payload properties contains the most common headers used to generate a JWT, but you can add
more headers calling the method AddKeyValue and passing the Key and Value as parameters.
Example: if you want add a new record in the JWT Header with your name, use the following method
 

Header.AddKeyValue('name', 'John Smith');

 
After configuring the properties, to generate the JWT, just call the method Sign and will return the value of the JWT.
 

526
COMPONENTS

WebSocket Client and JWT


TsgcWebSocketClient allows the use of JWT when connecting to WebSocket servers, just create a new JWT client
and assign to Authentication.Token.JWT property.
 

oClient := TsgcWebSocketClient.Create(nil);
oClient.URL := 'ws://www.esegece.com:2052';

oJWT := TsgcHTTP_JWT_Client.Create(nil);
oJWT.JWTOptions.Header.alg := jwtRS256;
oJWT.JWTOptions.Payload.sub := '1234567890';
oJWT.JWTOptions.Payload.iat := 1516239022;

oClient.Authentication.Enabled := True;
oClient.Authentication.URL.Enabled := False;
oClient.Authentication.Token.Enabled := True;
oClient.Authentication.Token.JWT := oJWT;
oClient.Active := True;

HTTP Clients and JWT


TsgcHTTP2Client and TsgcHTTP1Client allows the use of JWT when connecting to HTTP/2 servers, just create a
new JWT client and assign to Authentication.Token.JWT property.
 

oHTTP := TsgcHTTP2Client.Create(nil);

oJWT := TsgcHTTP_JWT_Client.Create(nil);
oJWT.JWTOptions.Header.alg := jwtRS256;
oJWT.JWTOptions.Payload.sub := '1234567890';
oJWT.JWTOptions.Payload.iat := 1516239022;

oHTTP.Authentication.Token.JWT := oHTTP;
oHTTP.Get('https://your.api.com');

Expiration
The Authorization Token can be re-created every time you send an HTTP request using an HTTP client or can be
reused several times till it expires.
Example: calling Apple APNs using Tokens, requires that the token is reused at least during 20 minutes and at a
maximum of 1 hour. Use the Property RefreshTokenAfter to set the seconds when the token will expire, for exam­
ple after 30 minutes.

RefreshTokenAfter = 60 * 40.

Create JWT Signature


You can create JWT Signatures manually to use on applications that doesn't make use of WebSocket or HTTP
Protocol, or if you are using components from third-parties applications and you only need the JWT Token.
 

527
COMPONENTS

In order to obtain the JWT Signature, just create a new instance of the JWT Client and fill the properties manually,
when all properties are set, call the method Sign and it will return the JWT Token.
 

oJWT := TsgcHTTP_JWT_Client.Create(nil);
// ... header
oJWT.JWTOptions.Header.alg := jwtHS256;
oJWT.JWTOptions.Algorithms.HS.Secret := '79F66F1E-E998-436B-8A0A-3E5DEFA4FD9E';
// ... payload
oJWT.JWTOptions.Payload.jti := '9B66FB94-B761-42B1-A1AF-3C44233DBE87';
oJWT.JWTOptions.Payload.iat := 1630925658;
oJWT.JWTOptions.Payload.iss := '2886EC7547B7BA6A9009';
oJWT.JWTOptions.Payload.exp := 1630933158;
// ... custom payload values
oJWT.JWTOptions.Payload.ClearKeyValues;
oJWT.JWTOptions.Payload.AddKeyValue('origin', 'www.yourwebsite.com');
oJWT.JWTOptions.Payload.AddKeyValue('ip', '69.39.46.178');
// ... get JWT Token
ShowMessage(oJWT.Sign);

528
COMPONENTS

JWT | TsgcHTTP_JWT_Server
The TsgcHTTP_JWT_Server component allows to decode and validate JWT tokens received in WebSocket
Handshake when using WebSocket protocol or as HTTP Header when using HTTP protocol.
 

Configuration
You can configure the following properties in the JWTOptions property of the component:
 
If the Signature is validated using a Public Key (RS and ES algorithms), set the value in the PublicKey property of
the Algorithm.
If the Signature is validated using a Secret (HS algorithms), set the value in the Secret property of the Algorithm.
 
To validate JWT tokens, just attach a TsgcHTTP_JWT_Server instance to Authentication.JWT.JWT property of
the WebSocket/HTTP Server.
 

oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 80;

oJWT := TsgcHTTP_JWT_Server.Create(nil);
oJWT.JWTOptions.Algorithms.RS.PublicKey.Text := 'public key here';

oServer.Authorization.Enabled := True;
oServer.Authorization.JWT.JWT := oJWT;
oServer.Active := True;

Checks property allows to enable some checks in the Payload of JWT, by default checks if the issued dates are
valid.

Events
Use the following events to control the flow of JWT Validating Token.
 
OnJWTBeforeRequest
 
The event is called when a new HTTP / WebSocket connection is detected and before any validation is done.
This connection can contain or not a JWT Token.
If you don't want to process this Connection using JWT Validation, just set the Cancel parameter to True (means
that this connection will bypass JWT validations).
By default, all connections continue the process of JWT validation.
 
 
OnJWTBeforeValidateToken
 
The event is called when the connection contains an Authorization token and before is validated.
If you don't want to validate this token, just set the Cancel parameter to True (means that this connection will by­
pass JWT validations).
By default, all connections continue the process of JWT validation.
 
 
OnJWTBeforeValidateSignature
 
This event is called after the token has been decoded, so using Header and Payload parameters you have ac­
cess to the content of JWT and before the signature is validated.

529
COMPONENTS

The parameter Secret is the secret that will be used to validate the signature and uses the PublicKey or Secret of
the JWTOptions property. If this Token must be validated with another secret, the new value can be set to Secret
parameter.
By default, all signatures are validated
 
 
OnJWTAfterValidateToken
 
The event is called after the signature has been validated, the parameter Valid shows if the signature is correct or
not. If it's not correct the connection will be closed, otherwise the connection will continue.
You can access to the content of Header and Payload of JWT using the arguments provided.
If there is any error validating the JWT, will be informed in the Error argument.
 
 
OnJWTException
 
If there is any exception while processing the JWT Decoding and Validation, this event will be called with the con­
tent of error.

530
COMPONENTS

Amazon AWS | SQS


What is Amazon SQS?
Amazon Simple Queue Service (SQS) is a fully managed message queuing service that enables you to decouple
and scale microservices, distributed systems, and serverless applications. SQS eliminates the complexity and over­
head associated with managing and operating message oriented middleware, and empowers developers to focus
on differentiating work. Using SQS, you can send, store, and receive messages between software components at
any volume, without losing messages or requiring other services to be available.
 

Benefits
Eliminate administrative overhead
 
With SQS, there is no upfront cost, no need to acquire, install, and configure messaging software, and no
time-consuming build-out and maintenance of supporting infrastructure.
 
Reliably deliver messages
 
SQS lets you decouple application components so that they run and fail independently, increasing the over­
all fault tolerance of the system.
 
Keep sensitive data secure
 
You can use Amazon SQS to exchange sensitive data between applications using server-side encryption
(SSE) to encrypt each message body.
 
Scale elastically and cost-effectively
 
SQS scales elastically with your application so you don’t have to worry about capacity planning and pre-pro­
visioning.
 
 

WorkFlow
The following scenario describes the lifecycle of an Amazon SQS message in a queue, from creation to deletion.

531
COMPONENTS

 
 

Getting Started with Amazon SQS


Before you begin, complete the steps in Setting Up Amazon SQS.
 
Step 1: Create a Queue
 
1. Sign in to the Amazon SQS console.
2. Choose Create New Queue.
3. On the Create New Queue page, ensure that you're in the correct region and then type the Queue Name.
4. Standard is selected by default. Choose FIFO.
5. To create your queue with the default parameters, choose Quick-Create Queue.
 
Your new queue is created and selected in the queue list.
 
Step 2: Send a Message
 
After you create your queue, you can send a message to it. The following example shows sending a message to an
existing queue.
 
1. From the queue list, select the queue that you've created.
2. From Queue Actions, select Send a Message.
3. Your message is sent and the Send a Message to QueueName dialog box is displayed, showing the attribut­
es of the sent message.

532
COMPONENTS

 
Step 3: Receive and Delete Your Message
 
After you send a message into a queue, you can consume it (retrieve it from the queue). When you request a mes­
sage from a queue, you can't specify which message to get. Instead, you specify the maximum number of mes­
sages (up to 10) that you want to get.
 
Step 4: Delete Your Queue
 
If you don't use an Amazon SQS queue (and don't foresee using it in the near future), it is a best practice to delete
it from Amazon SQS.

SQS Client

// TsgcHTTPAWS_SQS_Client is the component used for connect to Amazon SQS.


// Client connects using HTTPs protocol and authenticates using Access Key provided by Amazon.
 
// Before you try to connect to SQS service, you must set some data in AWSOptions property.
 
// Region: your endpoint region, example: us-east-1.
// AccessKey: access key provided by Amazon.
// SecretKey: secret key provided by Amazon.
 
// The following methods are supported by SQS client:
 
// AddPermission
// Adds a permission to a queue for a specific principal. This allows sharing access to the queue.
 
// ChangeMessageVisibility
// Changes the visibility timeout of a specified message in a queue to a new value. The default visibility timeout for a
// The minimum is 0 seconds. The maximum is 12 hours.
 
// ChangeMessageVisibilityBatch
 
// Changes the visibility timeout of multiple messages. This is a batch version of ChangeMessageVisibility.
// The result of the action on each message is reported individually in the response. You can send up to 10 ChangeMessag
 
// CreateQueue
// Creates a new standard or FIFO queue. You can pass one or more attributes in the request.
 
  vURL := SQS.CreateQueue('sqs_queue');
  if vURL  '' then
    DoLog('#CreateQueue: ' + vURL);
 
// DeleteMessage
// Deletes the specified message from the specified queue. To select the message to delete, use the ReceiptHandle of the
 
  if SQS.DeleteMessage('sqs_queue', '...receipt handle goes here...') then
    DoLog('#DeleteMessage: ok');
  else
    DoLog('#DeleteMessage: error');
 
// DeleteMessageBatch
// Deletes up to ten messages from the specified queue. This is a batch version of DeleteMessage. The result of the acti
 
// DeleteQueue
// Deletes the queue specified by the queue name, regardless of the queue's contents.
 
  if SQS.DeleteQueue(txtQueueName.Text) then
    DoLog('#Delete Queue: ok')
  else
    DoLog('#Delete Queue: error');
 
// GetQueueAttributes
// Gets attributes for the specified queue.
 
  oAttributes := TsgcSQSAttributes.Create;
  Try
    if SQS.GetQueueAttributes('sqs_queue', oAttributes) then

533
COMPONENTS

    begin
      for i := 0 to oAttributes.Count - 1 do
        DoLog('#Attribute: ' + TsgcSQSAttribute(oAttributes.Item[i])
          .AttributeName + ' ' + TsgcSQSAttribute(oAttributes.Item[i])
          .AttributeValue);
    end
    else
      DoLog('#GetQueueAttributes: error');
  Finally
    FreeAndNil(oAttributes);
  End;
 
// GetQueueUrl
// Returns the URL of an existing Amazon SQS queue.
  
// ListDeadLetterSourceQueues
// Returns a list of your queues that have the RedrivePolicy queue attribute configured with a dead-letter queue.
 
// ListQueueTags
// List all cost allocation tags added to the specified Amazon SQS queue.
 
// PurgeQueue
// Deletes the messages in a queue specified by the QueueName parameter.
 
  if SQS.PurgueQueue('sqs_queue') then
    DoLog('#PurgueQueue: ok')
  else
    DoLog('#PurgueQueue: error');
 
// ReceiveMessage
// Retrieves one or more messages (up to 10), from the specified queue.
 
  oResponses := TsgcSQSReceiveMessageResponses.Create;
  Try
    if SQS.ReceiveMessage('sqs_test', oResponses) then
    begin
      for i := 0 to oResponses.Count - 1 do
      begin
        DoLog('#ReceiveMessage: ' + TsgcSQSReceiveMessageResponse(oResponses.Item[i]).Body);
        FReceiptHandle := TsgcSQSReceiveMessageResponse(oResponses.Item[i]).ReceiptHandle;
      end;
    end;
  Finally
    FreeAndNil(oResponses);
  End;
 
// RemovePermission
// Revokes any permissions in the queue policy that matches the specified Label parameter.
 
// SendMessage
// Delivers a message to the specified queue.
 
  if SQS.SendMessage('sqs_queue', 'My First Message') then
    DoLog('#SendMessage: ok')
  else
    DoLog('#SendMessage: error');
 
// SendMessageBatch
// Delivers up to ten messages to the specified queue. This is a batch version of SendMessage.
 
// SetQueueAttributes
// Sets the value of one or more queue attributes. When you change a queue's attributes, the change can take up to 60 se
// for most of the attributes to propagate throughout the Amazon SQS system.
 
  oAttributes := TsgcSQSAttributes.Create;
  Try
    oAttributes.AddSQSAttribute(sqsatVisibilityTimeout, '45');
    if SQS.SetQueueAttributes('sqs_queue', oAttributes) then
      DoLog('#SetQueueAttributes: ok')
    else
      DoLog('#SetQueueAttributes: error');
  Finally
    FreeAndNil(oAttributes);
  End;
 
// TagQueue
// Add cost allocation tags to the specified Amazon SQS queue.
 
// UntagQueue
// Remove cost allocation tags from the specified Amazon SQS queue.

534
COMPONENTS

Events
OnSQSBeforeRequest
 
This event is called before sqs component does an HTTP request. You can get access to URL parameter and if
Handled parameter is set to True, means component won't do an HTTP request.
 
OnSQSError
 
If there is any error when component do a request, this event will be called with Error Code and Error Description.
 
OnSQSResponse
 
This event is called after an HTTP request with raw response from server.
 

535
COMPONENTS

Google Cloud | Google OAuth2 Keys


In order to use the sgcWebSockets Google Cloud components and Authenticate using OAuth2, first you must ob­
tain the OAuth2 Key from Google Cloud.
Find below the steps to get Google OAuth2 Keys and how configure in our PubSub sample application.
 
First login to your Google Cloud Account and use an existing project or create a new one.
After that, go to Credentials menu and press the button CREATE CREDENTIALS, select the option OAuth Client
ID.
 

 
Select your application type and set a description name
 

 
If successful, you will get your Client Id and Client Secret
 

536
COMPONENTS

 
Don't share your OAuth2 data with anyone!
Now copy to the sgcWebSockets PubSub sample, and add the Project Id (NOT the project name)
 

537
COMPONENTS

 
This is how will must be configured in sgcWebSocket PubSub sample
 

538
COMPONENTS

 
Then you can try to create a new topic for example, the first time, you must authorize the OAuth2 connection, so a
new web-browser will be shown to request an authorization to access your account with the OAuth2 credentials
provided by google
 

539
COMPONENTS

 
Allow the connection, and if successful you can start to work with this API
 

540
COMPONENTS

 
 

541
COMPONENTS

Google Cloud | Google Service Accounts


In order to use the sgcWebSockets Google Cloud components and Authenticate using Service Accounts, first you
must obtain the Private Key Certificate
from Google Cloud.
Find below the steps to get Google Private Key Certificate and how configure in our PubSub sample application.
 
First login to your Google Cloud Account and use an existing project or create a new one.
 

 
Select CREATE SERVICE ACCOUNT and a new page will be shown where you must set the service account
name and description
 

 
Then select at least one Role, I select PubSub Admin to allow the client publish and subscribe topics, but you can
select other role with less privileges
 

542
COMPONENTS

 
Press CONTINUE and finally you can grant access to other users
 

 
Press DONE when you finish and a new record will be shown
 

543
COMPONENTS

 
The next step is create a new Key, so select the option Create Key in actions column. Select JSON to download the
configuration in JSON format and a new Key will be created
 

 
Finally you only need to fill the data provided by google in the sgcWebSockets PubSub client. You can use Load­
SettingsFromFile to load the configuration JSON file.
 

544
COMPONENTS

545
COMPONENTS

Google Cloud | Pub/Sub


What is Google Cloud Pub/Sub?
Pub/Sub brings the flexibility and reliability of enterprise message-oriented middleware to the cloud. At the same
time, Pub/Sub is a scalable, durable event ingestion and delivery system that serves as a foundation for modern
stream analytics pipelines. By providing many-to-many, asynchronous messaging that decouples senders and re­
ceivers, it allows for secure and highly available communication among independently written applications. Pub/
Sub delivers low-latency, durable messaging that helps developers quickly integrate systems hosted on the Google
Cloud Platform and externally.
 

Features
 
At­least­once de­
livery Synchro­ Exactly­once pro­
Open Open APIs
nous, cross-zone cessing Cloud
and client libraries
message replica­ Dataflow supports
in seven languages
tion and per­mes­ reliable, expressive,
support cross-cloud
sage receipt track­ exactly­once pro­
and hybrid deploy­
ing ensures at- cessing of Cloud
ments.
least-once delivery Pub/Sub streams.
at any scale.
Global by default No provisioning, Compliance and
Publish from any­ auto-everything security Cloud Pub/
where in the world Cloud Pub/Sub Sub is a HIPAA-
and consume from does not have compliant service,
anywhere, with shards or partitions. offering fine-grained
consistent latency. Just set your quota, access controls and
No replication nec­ publish, and con­ end­to­end encryp­
essary. sume. tion.
Integrated Take
Seek and replay
advantage of inte­
Rewind your back­
grations with multi­
log to any point in
ple services, such
time or a snapshot,
as Cloud Storage
giving the ability to  
and Gmail update
reprocess the mes­
events and Cloud
sages. Fast forward
Functions for
to discard outdated
serverless event-
data.
driven computing.
 

Publisher-subscriber relationships
A publisher application creates and sends messages to a topic. Subscriber applications create a subscription to a
topic to receive messages from it. Communication can be one-to-many (fan-out), many-to-one (fan-in), and many-
to-many.
 

546
COMPONENTS

Common use cases


 
• Balancing workloads in network clusters. For example, a large queue of tasks can be efficiently distrib­
uted among multiple workers, such as Google Compute Engine instances.
• Implementing asynchronous workflows. For example, an order processing application can place an order
on a topic, from which it can be processed by one or more workers.
• Distributing event notifications. For example, a service that accepts user signups can send notifications
whenever a new user registers, and downstream services can subscribe to receive notifications of the event.
• Refreshing distributed caches. For example, an application can publish invalidation events to update the
IDs of objects that have changed.
• Logging to multiple systems. For example, a Google Compute Engine instance can write logs to the moni­
toring system, to a database for later querying, and so on.
• Data streaming from various processes or devices. For example, a residential sensor can stream data to
backend servers hosted in the cloud.
• Reliability improvement. For example, a single-zone Compute Engine service can operate in additional
zones by subscribing to a common topic, to recover from failures in a zone or region.
 
 

Authorization
Google Pub/Sub component client can login to Google Servers using the following methods:
 
• gcaOAuth2: OAuth2 protocol
• gcaJWT: JWT tokens.
 
OAuth2
 
The login is done using a webbrowser where the user logins with his own user and authorizes the PubSub re­
quests.
 
• GoogleCloudOptions.OAuth2.ClientId: is the ClientID provided by Google to Authenticate through OAuth2
protocol.
• GoogleCloudOptions.OAuth2.ClientSecret: is the Client Secret string provided by Google to Authenticate
through OAuth2 protocol.

547
COMPONENTS

• GoogleCloudOptions.OAuth2.Scope: is the scope of OAuth2, usually there is no need to modify the de­
fault value unless you need to get more access than default.
• GoogleCloudOptions.OAuth2.LocalIP: OAuth2 protocol requires a server listening answer from Authenti­
cation server, this is the IP or DNS. By default is 127.0.0.1.
• GoogleCloudOptions.OAuth2.LocalPort: Local server listening port.
• GoogleCloudOptions.OAuth2.RedirectURL: if you need to set a redirect url different from LocalPort + Lo­
calIP, you can set in this property (example: http://127.0.0.1:8080/oauth2).
 
Service Accounts
 
The login is done signing the requests using a private key provided by google, these method is recommended for
automated services or applications without user interaction.
 
• GoogleCloudOptions.JWT.ClientEmail: is the Client Email name provided creating the new service ac­
count. "client_email" node in the JSON configuration file.
• GoogleCloudOptions.JWT.PrivateKeyId: is the Private Key Id provided by google. "private_key_id" node
in the JSON configuration file.
• GoogleCloudOptions.JWT.PrivateKey: is the Private Key certificate provided by google. "private_key"
node in the JSON configuration file.
 
When a new service account is created, you can download a JSON file with all configurations. This file can be
processed by the PubSub component, just call the method LoadSettingsFromFile and pass the JSON filename as
argument.
 
 

Most common uses


• Configuration
• Google OAuth2 Keys
• Service Accounts
 

Google Pub/Sub Client


 
OAuth2
 
In order to work with Google Pub/Sub API, sgcWebSockets Pub/Sub component uses OAuth2 as default authenti­
cation, so first you must set your ClientId and ClientSecret from your google account.
 

oPubSub := TsgcHTTPGoogleCloud_PubSub_Client.Create(nil);
oPubSub.GoogleCloudOptions.Authorization := gcaOAuth2;
oPubSub.GoogleCloudOptions.OAuth2.ClientId := '... your google client id...';
oPubSub.GoogleCloudOptions.OAuth2.ClientSecret := '... your google client secret...';

 
Service Accounts
 
Service Accounts requires to build a JWT and pass as an Authorization Token
 

oPubSub := TsgcHTTPGoogleCloud_PubSub_Client.Create(nil);
oPubSub.GoogleCloudOptions.Authorization := gcaJWT;
oPubSub.GoogleCloudOptions.JWT.ClientEmail := '...google email...';
oPubSub.GoogleCloudOptions.JWT.PrivateKeyId := '...private key id...';
oPubSub.GoogleCloudOptions.JWT.PrivateKey.Lines.Text := '...private key certificate...';

This is required in order to get an Authorization Token Key from Google which will be used for all Rest API calls.
 
All methods return a response, which may be successful or return an error.
 

548
COMPONENTS

Projects.Snapshots

 
Para­
Method Description Example
meters
Creates a snapshot
from the requested
subscription. Snap­
shots are used in
subscriptions.seek
project, operations, which al­
snap­ low you to manage
CreateS­ CreateSnapshot('pubsub-270909',
shot, message acknowl­
napshot 'snapshot-1', 'subscription-1')
sub­ edgments in bulk.
scription That is, you can set
the acknowledgment
state of messages in
an existing subscrip­
tion to the state cap­
tured by a snapshot.
project,
DeleteS­ Removes an existing DeleteSnapshot('pubsub-270909',
snap­
napshot snapshot 'snapshot-1')
shot
List­
Lists the existing
Snap­ project ListSnapshots('pubsub-270909')
snapshots
shots
 
 

Projects.Subscriptions

 
Para­
Method Description Example
meters
Ac­
knowl­
edge­      
Sub­
scription
Creates a subscrip­
tion to a given topic.
If the subscription
project, already exists, re­
Create­
subscrip­ turns CreateSubscription('pubsub-270909',
Sub­
tion, top­ ALREADY_EXISTS. 'subscription-1', 'topic-1')
scription
ic If the corresponding
topic doesn't exist,
returns
NOT_FOUND.
Deletes an existing
Delete­ project,
subscription. All DeleteSubscription('pubsub-270909',
Sub­ subscrip­
messages retained 'subscription-1')
scripton tion
in the subscription

549
COMPONENTS

are immediately
dropped.
project, Gets the configura­
GetSub­ GetSubscription('pubsub-270909',
subscrip­ tion details of a sub­
scription 'subscription-1')
tion scription.
ListSub­
Lists matching sub­ ListSubscriptions('pubsub-270909',
scrip­ project
scriptions. 'subscription-1')
tions
Modifies the ack
deadline for a spe­
cific message. This
method is useful to
indicate that more
time is needed to
process a message
Modify­
project, by the subscriber, or
Ack­
subscrip­ to make the mes­
Deadli­  
tion, Ack­ sage available for
neSub­
Ids redelivery if the pro­
scription
cessing was inter­
rupted. Note that
this does not modify
the subscription­lev­
el ackDeadlineSec­
onds used for sub­
sequent messages.
Modifies the Push­
Config for a speci­
fied
subscription.This
may be used to
change a push sub­
scription to a pull
one (signified by an
Modify­
empty PushConfig)
Push­ project,
or vice versa, or
Config­ subscrip­  
change the end­
Sub­ tion
point URL and other
scription
attributes of a push
subscription. Mes­
sages will accumu­
late for delivery con­
tinuously through
the call regardless
of changes to the
PushConfig.
Pulls messages
from the server. The
project, server may return
pull('pubsub-270909', 'subscrip-
Pull subscrip­ UNAVAILABLE if
tion-1')
tion there are too many
concurrent pull re­
quests pending for

550
COMPONENTS

the given subscrip­
tion.
Seeks an existing
subscription to a
point in time or to a
given snapshot,
whichever is provid­
ed in the request.
Snapshots are used
in
subscriptions.seek
operations, which
project, allow you to man­
subscrip­ age message ac­
Seek tion, knowledgments in  
timeUTC, bulk. That is, you
snapshot can set the ac­
knowledgment state
of messages in an
existing subscription
to the state cap­
tured by a snap­
shot. Note that both
the subscription and
the snapshot must
be on the same top­
ic.
 

Projects.Topics

 
Parame­
Method Description Example
ters
Create­ project, Creates the given top­ CreateTopic('pubsub-270909',
Topic topic ic with the given name 'topic-1')
Deletes the topic with
the given name. Re­
turns NOT_FOUND if
the topic does not ex­
ist. After a topic is
Delete­ project, deleted, a new topic DeleteTopic('pubsub-270909',
Topic topic may be created with 'topic-1')
the same name; this
is an entirely new top­
ic with none of the old
configuration or sub­
scriptions.
project, Gets the configuration GetTopic('pubsub-270909',
GetTopic
topic of a topic. 'topic-1')
List­
project Lists matching topics. ListTopics('pubsub-270909')
Topics

551
COMPONENTS

Adds one or more


project, messages to the top­ Publish('pubsub-270909',
Publish topic, mes­ ic. Returns 'topic-1', 'My First PubSub
sage NOT_FOUND if the Message.')
topic does not exist.
 
 

Projects.Topics.Subscriptions

 
De­
Para­
Method scrip­ Example
meters
tion
Lists the
List­
names of
Topic­
project, the sub­ ListTopicSubscriptions('pubsub-270909',
Sub­
topic scriptions 'topic-1')
scrip­
on this
tions
topic.
 
 
 

Most common methods


Find below the most common methods used with Google Cloud Pub/Sub API
 

How create a new Topic


Create a new topic for project with id: pubsub-270909 and topic name topic-1.

oPubSub := TsgcHTTPGoogleCloud_PubSub_Client.Create(nil);
oPubSub.GoogleCloudOptions.OAuth2.ClientId := '... your google client id...';
oPubSub.GoogleCloudOptions.OAuth2.ClientSecret := '... your google client secret...';
oPubSub.CreateTopic('pubsub-270909', 'topic-1');

Response from Server

{
  "name": "projects/pubsub-270909/topics/topic-1"
}

Publish a message
Publish a new message in new topic created

oPubSub := TsgcHTTPGoogleCloud_PubSub_Client.Create(nil);
oPubSub.GoogleCloudOptions.OAuth2.ClientId := '... your google client id...';
oPubSub.GoogleCloudOptions.OAuth2.ClientSecret := '... your google client secret...';
oPubSub.Publish('pubsub-270909', 'topic-1', 'My First Message from sgcWebSockets.'));

Response from Server

{
  "messageIds": [
    "1050732082561505"

552
COMPONENTS

  ]
}

Publish a Message with Attributes

oPubSub := TsgcHTTPGoogleCloud_PubSub_Client.Create(nil);
oPubSub.GoogleCloudOptions.OAuth2.ClientId := '... your google client id...';
oPubSub.GoogleCloudOptions.OAuth2.ClientSecret := '... your google client secret...';
oAttributes := TStringList.Create;
Try
  oAttributes.CommaText := 'origin=gcloud-sample,username=gcp';
  oPubSub.Publish('pubsub-270909', 'topic-1', 'My First Message from sgcWebSockets.', oAttributes, 'username'));
Finally
  oAttributes.Free;
end;

How Create a new Subscription


Create a new subscription for project with id: pubsub-270909, with subscription name subscription-1 and topic-1

oPubSub := TsgcHTTPGoogleCloud_PubSub_Client.Create(nil);
oPubSub.GoogleCloudOptions.OAuth2.ClientId := '... your google client id...';
oPubSub.GoogleCloudOptions.OAuth2.ClientSecret := '... your google client secret...';
oPubSub.CreateSubscription('pubsub-270909', 'subscription-1', 'topic-1');

Response from Server

{
  "name": "projects/pubsub-270909/subscriptions/subscription-1",
  "topic": "projects/pubsub-270909/topics/topic-1",
  "pushConfig": {},
  "ackDeadlineSeconds": 10,
  "messageRetentionDuration": "604800s",
  "expirationPolicy": {
    "ttl": "2678400s"
  }
}

How Read messages from Subscription


Read messages from previous subscription created.

oPubSub := TsgcHTTPGoogleCloud_PubSub_Client.Create(nil);
oPubSub.GoogleCloudOptions.OAuth2.ClientId := '... your google client id...';
oPubSub.GoogleCloudOptions.OAuth2.ClientSecret := '... your google client secret...';
oPubSub.pubsub.Pull('pubsub-270909', 'subscription-1');

Response from Server

{
  "receivedMessages": [
    {
      "ackId": "PjA-RVNEUAYWLF1GSFE3GQhoUQ5PXiM_NSAoRREFC08CKF15MEorQVh0Dj4N",
      "message": {
        "data": "TXkgRmlyc3QgTWVzc2FnZSBmcm9tIHNnY1dlYlNvY2tldHMu",
        "messageId": "1050732082561505",
        "publishTime": "2020-03-14T15:25:31.505Z"
      }
    }
  ]
}

Message is received Encode in Base64, so you must decode first to read contents.

553
COMPONENTS

sgcBase_Helpers.DecodeBase64('TXkgRmlyc3QgTWVzc2FnZSBmcm9tIHNnY1dlYlNvY2tldHMu=');

554
COMPONENTS

Google Cloud | Calendar


The Google Calendar API lets you integrate your app with Google Calendar, creating new ways for you to engage
your users. The Calendar API lets you display, create and modify calendar events as well as work with many other
calendar-related objects, such as calendars or access controls.

API Resources
Google Calendar uses the following resources:
 
• Event: An event on a calendar containing information such as the title, start and end times, and attendees.
Events can be either single events or recurring events. An event is represented by an Event resource. The
Events collection for a given calendar contains all event resources for that calendar.
• Calendar: A calendar is a collection of events. Each calendar has associated metadata, such as calendar
description or default calendar time zone. The metadata for a single calendar is represented by a Calendar
resource. The Calendars collection contains Calendar resources for all existing calendars.
• CalendarList: A list of all calendars on a user's calendar list in the Calendar UI. The metadata for a single
calendar that appears on the calendar list is represented by a CalendarListEntry resource. This metadata in­
cludes user­specific properties of the calendar, such as its color or notifications for new events. The Calen­
darList collection contains all CalendarListEntry resources for a given user. For a further explanation of the
difference betweeen the Calendars and CalendarList collections, see Calendar and Calendar List
• Setting: A user preference from the Calendar UI, such as the user's time zone. A single user preference is
represented by a Setting Resource. The Settings collection contains all Setting resources for a given user.
• ACL: An access control rule granting a user (or a group of users) a specified level of access to a calendar. A
single access control rule is represented by an ACL resource. The ACL collection for a given calendar con­
tains all ACL resources that grant access to that calendar.
• Color: A color presented in the Calendar UI. The Colors resource represents the set of all colors available in
the Calendar UI, in two groups: colors available for events and colors available for calendars.
• Free/busy: A time when a calendar has events scheduled is considered "busy", a time when a calendar has
no events is considered "free". The Freebusy resource allows querying for the set of busy times for a given
calendar or set of calendars.
 

Main Features
• Fully Featured Google Calendar Client API V3.
• All Methods supported by API can be called using client API.
• Client requests using HTTP/2 protocol (*only Enterprise Edition).
• Automatic Handling of partial responses using PageNextToken.
• Easy access to Calendar and Event data properties.
 

Configuration
Google Calendar component client has the following properties:
 
• GoogleCloudOptions.OAuth2.ClientId: is the ClientID provided by Google to Authenticate through OAuth2
protocol.
• GoogleCloudOptions.OAuth2.ClientSecret: is the Client Secret string provided by Google to Authenticate
through OAuth2 protocol.
• GoogleCloudOptions.OAuth2.Scope: is the scope of OAuth2, usually there is no need to modify the de­
fault value unless you need to get more access than default.
• GoogleCloudOptions.OAuth2.LocalIP: OAuth2 protocol requires a server listening answer from Authenti­
cation server, this is the IP or DNS. By default is 127.0.0.1.
• GoogleCloudOptions.OAuth2.LocalPort: Local server listening port.
• GoogleCloudOptions.OAuth2.RedirectURL: if you need to set a redirect url different from LocalPort + Lo­
calIP, you can set in this property (example: http://127.0.0.1:8080/oauth2).
 

555
COMPONENTS

You can modify the Scopes of your client API using Scopes property, just select which scopes are supported by
your client.
 

Most common uses


• Configuration
• Google Calendar Refresh Token
 
• Synchronization
• Google Calendar Sync Calendars
• Google Calendar Sync Events
 
 

Synchronize Calendars
TsgcHTTPGoogleCloud_Calendar_Client component allows to synchronize the calendars using direct Google API
calls or using our easy Calendars methods to synchronize the calendars.
 
Method Parameters Description
aSummary: the
NewCalen­ Creates a new Calen­
title of the cal­
dar dar
endar.
DeleteCalen­ aId: identifier of Deletes an existing Cal­
dar the calendar. endar.
aResource:
UpdateCal­ Updates an existing
object with the
endar Calendar.
calendar data.
Loads all calendars and
LoadCalen­
  Calendars property is
dars
filled with this data.
aSyncToken:
Loads all changes in
LoadCalen­ last token used
your calendars from To­
darsChanged to update your
ken set.
calendar.
 
Calendar Client has a property called Calendars, where you can access to Calendar Data after calling any of previ­
ous methods, this property is synchronized automatically.
 
 

Synchronize Events
TsgcHTTPGoogleCloud_Calendar_Client component allows to synchronize the events using direct Google API
calls or using our easy Event methods to synchronize the Events.
 
Method Parameters Description
aCalendarId: id
of the calendar.
NewEvent aResource: Creates a new Event.
object with the
event data.
aCalendarId: id
of the calendar. Deletes an existing
DeleteEvent
aId: identifier of Event.
the event.

556
COMPONENTS

aCalendarId: id
of the calendar.
Updates an existing
UpdateEvent aResource:
Event.
object with the
event data.
aCalendarId: id Loads all events of
LoadEvents
of the calendar. the calendar.
aCalendarId: id
of the calendar.
Loads all events of
LoadE­ aSyncToken:
the calendar from To­
ventsChanged last token used
ken set.
to update your
calendar.
 
You can access to events data, using the property Calendars, select any of the existing calendars of the list and
accessing to Events property.
 
 

Google Calendar API Calls

Method Description
Deletes an access con­
ACL_Delete
trol rule.
Returns an access con­
ACL_Get
trol rule.
Creates an access con­
ACL_Insert
trol rule.
Returns the rules in the
ACL_List access control list for
the calendar.
Updates an access con­
trol rule. This method
ACL_Patch
supports patch seman­
tics.
Updates an access con­
ACL_Update
trol rule.
Watch for changes to
ACL_Watch
ACL resources.
 
 
Method Description
Removes a cal­
endar from the
CalendarList_Delete
user's calendar
list.
Returns a cal­
endar from the
CalendarList_Get
user's calendar
list.
Inserts an exist­
ing calendar in­
CalendarList_Insert
to the user's cal­
endar list.

557
COMPONENTS

Returns the cal­
endars on the
CalendarList_List
user's calendar
list.
Updates an ex­
isting calendar
on the user's
CalendarList_Patch calendar list.
This method
supports patch
semantics.
Updates an ex­
isting calendar
CalendarList_Update
on the user's
calendar list.
Watch for
changes to Cal­
CalendarList_Watch
endarList re­
sources.
 
 
Method Description
Clears a primary
calendar. This oper­
ation deletes all
Calendar_Clear events associated
with the primary
calendar of an ac­
count.
Deletes a sec­
ondary calendar.
Use calendars.clear
Calendar_Delete
for clearing all
events on primary
calendars.
Returns metadata
Calendar_Get
for a calendar.
Creates a sec­
Calendar_Insert
ondary calendar.
Updates metadata
for a calendar. This
Calendar_Patch
method supports
patch semantics.
Updates metadata
Calendar_Update
for a calendar.
 
 
Method Description
Stop watching re­
Channel_Stop sources through this
channel.
 
 
Method Description

558
COMPONENTS

Returns the color defini­
Color_Get tions for calendars and
events.
 
 
Method Description
Event_Delete Deletes an event.
Event_Get Returns an event.
Imports an event.
This operation is
used to add a pri­
Event_Import
vate copy of an ex­
isting event to a cal­
endar.
Event_Insert Creates an event.
Returns instances of
Event_Instances the specified recur­
ring event.
Returns events on
Event_List the specified calen­
dar.
Moves an event to
another calendar,
Event_Move
i.e. changes an
event's organizer.
Updates an event.
This method sup­
ports patch seman­
tics. The field values
you specify replace
the existing values.
Fields that you don’t 
Event_Patch specify in the re­
quest remain un­
changed. Array
fields, if specified,
overwrite the exist­
ing arrays; this dis­
cards any previous
array elements.
Creates an event
Event_QuickAdd based on a simple
text string.
Event_Update Updates an event.
Watch for changes
Event_Watch
to Events resources.
 
 
Method Description
Returns free/busy
Freebusy_Query information for a set
of calendars.
 
 

559
COMPONENTS

Method Description
Returns a single user
Settings_Get
setting.
Returns all user set­
Settings_List tings for the authenti­
cated user.
Watch for changes to
Settings_Watch
Settings resources.
 

560
COMPONENTS

Google Calendar | Load Calendars


The process to get all calendars of your account is very easy, just follow the next steps:
 
1. Call the method LoadCalendars.
2. If method returns True, then you can Access to Calendars property and iterate over the list to get access to
all Calendars.
 

oGoogleCalendar := TsgcHTTPGoogleCloud_Calendar_Client.Create(nil);
// ... configure OAuth2 options
oGoogleCalendar.GoogleCloudOptions.OAuth2.ClientId := 'google ClientId';
oGoogleCalendar.GoogleCloudOptions.OAuth2.ClientSecret := 'google ClientSecret';
// ... request calendars
if oGoogleCalendar.LoadCalendars then
begin
  // ... get calendars data
  for i := 0 to oGoogleCalendar.Calendars.Count - 1 do
    vCalendarTitle := oGoogleCalendar.Calendars.Calendar[i].Summary;
end
else
  raise Exception.Create('Error Calendar Sync');

561
COMPONENTS

Google Calendar | Sync Events


The process to get all calendars of your account is very easy, just follow the next steps:
 
1. Call the method LoadEvents and pass the CalendarId as parameter.
2. If method returns True, then you can Access to Calendars.Events property and iterate over the list to get
access to all Events of the calendar.
 

oGoogleCalendar := TsgcHTTPGoogleCloud_Calendar_Client.Create(nil);
// ... configure OAuth2 options
oGoogleCalendar.GoogleCloudOptions.OAuth2.ClientId := 'google ClientId';
oGoogleCalendar.GoogleCloudOptions.OAuth2.ClientSecret := 'google ClientSecret';
// ... request calendars first
oGoogleCalendar.LoadCalendars;
// ... request events from first calendar
oCalendar := TsgcGoogleCalendarItem(oGoogleCalendar.Calendars.Calendar[0]);
if oGoogleCalendar.LoadEvents(oCalendar.ID) then
begin
  // ... get events data
  for i := 0 to oCalendar.Events.Count - 1 do
    vEventTitle := oCalendar.Events[i].Summary;
end
else
  raise Exception.Create('Error Event Sync');

562
COMPONENTS

Google Calendar | RefreshToken


Google Calendar API uses OAuth2 to authenticate against google servers, sgcWebSockets has a component
which handles all the authentication process, but if your application closes and you try to connect again, you have 2
options:
 
1. Authenticate again using your Google APIs
2. Use the Refresh Token (if still valid), so you avoid the authentication process.
 

Using RefreshToken
The first time you Authenticate, use OnAuthToken event to save the RefreshToken if exists, you can save in an IN­
IFile for example:
 

procedure OnGoogleCalendarAuthToken(Sender: TObject; const TokenType, Token, Data: string);


var
  oINI: TINIFile;
  oJSON: TsgcJSON;
begin
  oJSON := TsgcJSON.Create(nil);
  Try
    oJSON.Read(Data);
    if oJSON.Node['refresh_token']  nil then
    begin
      oINI := TINIFile.Create(ChangeFileExt(Application.ExeName, '.ini'));
      Try
        oINI.WriteString('OAUTH2', 'Token', oJSON.Node['refresh_token'].Value);
      Finally
        oINI.Free;
      End;
    end;
  Finally
    oJSON.Free;
  End;
end;

Then when you start your application again, if there is a RefreshToken, call the method RefreshToken and pass the
token as argument (previously you must set the Google Calendar API keys). If successful, you will login to google
servers without re-authenticate again.
 

GoogleCalendar.RefreshToken('your refresh token here');

563
COMPONENTS

TsgcUDPClient
TsgcUDPClient implements the UDP Client based on Indy library.
 
UDP it's a connection less protocol where there is no assurance that message sent arrive to the destination but op­
posite to TCP protocol, it's much faster.
 
1. Drop a TsgcUDPClient component onto the form
 
2. Set Host and Port (default is 80) to connect to an available UDP Server.

oClient := TsgcUDPClient.Create(nil);
oClient.Host := '127.0.0.1';
oClient.Port := 80;

3. You can connect through an HTTP Proxy Server, you need to define proxy properties:
 
    Host: hostname of the proxy server.
    Port: port number of the proxy server.
    Username: user to authenticate, blank if anonymous.
    Password: password to authenticate, blank if anonymous.
 
4. If you want, you can handle the events
 
    OnUDPRead: called when a new message is received from the server. The message is in Bytes format.
 
    OnUDPException: called when there is any exception in the UDP protocol.
 
5. Call WriteData method to send any message to the UDP server.
 
 

Properties
    Host: IP or DNS name of the server.
 
    Port: Port used to connect to the host.
 
    LogFile: if enabled save socket messages to a specified log file, useful for debugging. The access to log file is
not thread safe if it's accessed from several threads.
 
Enabled: if enabled every time a message is received and sent by socket it will be saved on a file.
 
FileName: full path to the filename.
 
UnMaskFrames: by default True, means that saves the websocket messages sent unmasked.
 
    NotifyEvents: defines which mode to notify WebSocket events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 
    Proxy: here you can define if you want to connect through a Proxy Server, you can connect to the following
proxy servers:

564
COMPONENTS

pxyHTTP: HTTP Proxy Server.


pxySocks4: SOCKS4 Proxy Server.
pxySocks4A: SOCKS4A Proxy Server.
pxySocks5: SOCKS5 Proxy Server.
 

565
COMPONENTS

TsgcUDPServer
TsgcUDPServer implements the UDP Serverbased on Indy library.
 
UDP it's a connection less protocol where there is no assurance that message sent arrive to the destination but op­
posite to TCP protocol, it's much faster.
 
1. Drop a TsgcUDPServer component onto the form
 
2. Set the listening Port.

oClient := TsgcUDPServer.Create(nil);
oClient.Port := 80;

3. To start the server, set the property Active = true.


 
4. The following events are available:
 
    OnStartup: when the UDP server start listening.
 
    OnShutdown: when the UDP server stops listening.
 
    OnUDPRead: called when a new message is received from the server. The message is in Bytes format.
 
    OnUDPException: called when there is any exception in the UDP protocol.
 

Properties
    Bindings: used to manage IP and Ports.
 
    LogFile: if enabled save socket messages to a specified log file, useful for debugging.
 
Enabled: if enabled every time a message is received and sent by socket it will be saved on a file.
 
FileName: full path to the filename.
 
    NotifyEvents: defines which mode to notify WebSocket events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 
    WatchDog: if enabled, restart the server after unexpected disconnection.
 
Interval: seconds before reconnects.
 
Attempts: max number of reconnects, if zero, then unlimited.
 

566
COMPONENTS

STUN
STUN (Session Traversal Utilitiies for NAT) it's an IETF protocol used for real-time audio video in IP networks.
STUN is a server-client protocol, a STUN server usually operates on both UPD and TCP and listens on port 3478.
 
The main purpose of the STUN protocol is to enable a device running behind a NAT discover its public IP and what
type of NAT is.
 
STUN provides a mechanism to communicate between peers behind a NAT. The peers send a request to a STUN
server to know which is the public IP address and Port. The binding requests sent from client to server are used to
determine the IP and ports bindings allocated by NAT's. The STUN client sends a Binding request to the STUN
server, the server examines the source IP and Port used by client, and returns this information to the client.
 

 
The STUN server basically sends 2 types of responses: successful or error, every response has a list of attributes
which contains information about binding IP address, error code, reason of error...
 

Components
• TsgcSTUNClient: it's the client component that implements the STUN protocol and allows to send binding
requests to STUN servers.
 
• TsgcSTUNServer: it's the server component that implements the STUN protocol.

567
COMPONENTS

STUN | TsgcSTUNClient
TsgcSTUNClient is the client that implements the STUN protocol and allows to send binding requests to STUN
servers.
 
The components allows to use UDP and TCP as transport, and when used UDP as transport implements a Re­
transmission mechanism to re-send requests if the response not arrived after a small time.
 

Basic usage
Usually stun servers runs on UDP port 3478 and don't require authentication, so in order to send a STUN request
binding, fill the server properties to allow the client know where connect and Handle the events where the compo­
nent will receive the response from server.
 
Configure the server
• Host: the IP or DNS name of the server, example: stun.sgcwebsockets.com
• Port: the listening Server port, example: 3478
 
Call the method SendRequest, to send a request binding to STUN server.
 
Handle the events
• If the server returns a successful response, the event OnSTUNResponseSuccess will be called and you
can access to the Binding information reading the aBinding object.
• If the server returns an error, the event OnSTUNResponseError will be called and you can access the Error
Code and Reason reading the aError object.
 

oSTUN := TsgcSTUNClient.Create(nil);
oSTUN.Host := 'stun.sgcwebsockets.com';
oSTUN.Port := 3478;
oSTUN.SendRequest;

procedure OnSTUNResponseSuccess(Sender: TObject; const aSocket: TsgcSocketConnection;


  const aMessage: TsgcSTUN_Message; const aBinding: TsgcSTUN_ResponseBinding);
begin
  DoLog('Remote IP: ' + aBinding.RemoteIP + '. Remote Port: ' + IntToStr(aBinding.RemotePort));
end;

procedure OnSTUNResponseError(Sender: TObject; const aSocket: TsgcSocketConnection;


  const aMessage: TsgcSTUN_Message; const aError: TsgcSTUN_ResponseError);
begin
  DoLog('Error: ' + IntToStr(aError.Code) + ' ' + aError.Reason);
end;

Most common uses


• Bindings
• UDP Retransmissions
• Long Term Credentials
• • Attributes
 

Methods
There is a single method called SendRequest, which sends a request to STUN Server, requesting binding informa­
tion.

568
COMPONENTS

Properties
    Host: it's the IP Address or DNS name of STUN server where the client will send a binding request.
 
    Port: it's the listening port of STUN server, by default 3478.
 
    IPVersion: it's the Family Address, by default IPv4.
 
    Transport: it's the transport used to connect to STUN server, by default UDP.
 
    STUNOptions: here are defined the specific STUN options of client component
 
Fingerprint: if enabled, the message includes a fingerprint that aids to identify STUN messages from pack­
ets of other protocols when the two are multiplexed on the same transport address.
 
Software: if enabled, sends an attribute with the name of the software being used by the client.
 
Authentication: some STUN servers requires that requests are authenticated.
 
• Credentials:  there are 2 types of Authentication: LongTermCredentials and ShortTermCredentials.
By default the requests are not authenticated
• Username: the string that identifies the user.
• Password: the secret string.
 
    RetransmissionOptions: when messages are sent using UDP as transport, UDP doesn't includes a mechanism
to know if a message has arrived or not to other peer. This property allows to configure a mechanism to re-send
UDP messages if not arrived after a small time.
 
Enabled: if enabled, the message will be re-send until receives a confirmation or the maximum number of
retries has been reached.
 
RTO: retransmission time in milliseconds, by default 500ms. For example, assuming an RTO of 500 ms, re­
quests would be sent at times 0 ms, 500 ms, 1500 ms, 3500 ms, 7500 ms, 15500 ms, and 31500 ms.
 
MaxRetries: Max number of retries, by default 7.
 
    LogFile: if enabled save stun messages to a specified log file, useful for debugging. The access to log file is not
thread safe if it's accessed from several threads.
 
Enabled: if enabled every time a message is received and sent by client it will be saved on a file.
 
FileName: full path to the filename.
 
    NotifyEvents: defines which mode to notify WebSocket events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 

Events
    OnSTUNBeforeSend
 
This event is called before the stun client sends a message to the server. You can access to the message
properties through the aMessage parameter and modify if required.

569
COMPONENTS

 
    OnSTUNResponseSuccess
 
When the server processes successfully a request binding, it sends a message with the binding properties
(IP Address, Port and family) and other attributes, this event is called when the client receives this success­
ful response.
 
    OnSTUNResponseError
 
When there is any error in the response sent by server, this event is called with the error details.
 
    OnSTUNException
 
This event is called when there is any exception processing the STUN protocol messages.

570
COMPONENTS

STUN Client | UDP Retransmissions


When running STUN over UDP, it's possible that the STUN message might be dropped by the network. Reliability
of STUN request/response transactions is accomplished through retransmissions of the request message by the
client application itself.
 
A client should retransmit a STUN request message starting with an interval of RTO ("Retransmission TimeOut"),
doubling after each retransmission. The RTO is an estimate of the round-trip time.
 
By default, the sgcWebSockets STUN Client is already configured with a RTO of 500 ms and a Max Retries value
of 7.
 
For example, assuming an RTO of 500 ms, requests would be sent at times 0 ms, 500 ms, 1500 ms, 3500 ms,
7500 ms, 15500 ms, and 31500 ms. If the client has not received a response after 39500 ms, the client will consid­
er the transaction to have timed out.
 

oSTUN := TsgcSTUNClient.Create(nil);
oSTUN.Host := 'stun.sgcwebsockets.com';
oSTUN.Port := 3478;
oSTUN.RetransmissionOptions.Enabled := true;
oSTUN.RetransmissionOptions.RTO := 500;
oSTUN.RetransmissionOptions.MaxRetries := 7;
oSTUN.SendRequest;

571
COMPONENTS

STUN Client | Long Term Credentials


The long-term credential mechanism relies on a long-term credential, in the form of a username and password that
are shared between client and server. The credential is considered long-term since it is assumed that it is provi­
sioned for a user and remains in effect until the user is no longer a subscriber of the system or until it is changed.
 
You can configure the Long-term credentials in the sgcWebSockets STUN client using the following code.
 

oSTUN := TsgcSTUNClient.Create(nil);
oSTUN.Host := 'stun.sgcwebsockets.com';
oSTUN.Port := 3478;
oSTUN.STUNOptions.Authentication.Credentials := stauLongTermCredential;
oSTUN.STUNOptions.Authentication.Username := 'user_name';
oSTUN.STUNOptions.Authentication.Password := 'secret';
oSTUN.SendRequest;

 
If server requires long-term credentials and the credentials sent by the client are wrong, the will receive a 401
Unauthorized error as a response in the OnSTUNResponseError event.
 

572
COMPONENTS

STUN Client | Attributes


Every time a server sends a message to client, as a response message to a request binding, the STUN message
contains a list of attributes with information about the response.
 
You can access to these attributes, using the TsgcSTUN_Message class and accessing to Attributes properties,
which contains a list of TsgcSTUN_Attribute with useful information.
 

procedure OnSTUNResponseSuccess(Sender: TObject; const aSocket: TsgcSocketConnection;


  const aMessage: TsgcSTUN_Message; const aBinding: TsgcSTUN_ResponseBinding);
var
  i: Integer;
begin
  DoLog('#binding: ' + aBinding.RemoteIP + ':' + IntToStr(aBinding.RemotePort));
  for i := 0 to aMessage.Attributes.Count - 1 do
  begin
    case TsgcSTUN_Attribute(aMessage.Attributes.Items[i]).AttributeType of
      stmaFingerprint:
        DoLog('#fingerprint: ' + IntToStr(TsgcSTUN_Attribute_FINGERPRINT
          (aMessage.Attributes.Items[i]).Fingerprint));
      stmaSoftware:
        DoLog('#software: ' + TsgcSTUN_Attribute_SOFTWARE
          (aMessage.Attributes.Items[i]).Software);
      stmaResponse_Origin:
        DoLog('#response_origin: ' + TsgcSTUN_Attribute_RESPONSE_ORIGIN
          (aMessage.Attributes.Items[i]).Address + ':' +
          IntToStr(TsgcSTUN_Attribute_RESPONSE_ORIGIN(aMessage.Attributes.Items
          [i]).Port));
      stmaOther_Address:
        DoLog('#other_address: ' + TsgcSTUN_Attribute_OTHER_ADDRESS
          (aMessage.Attributes.Items[i]).Address + ':' +
          IntToStr(TsgcSTUN_Attribute_OTHER_ADDRESS(aMessage.Attributes.Items
          [i]).Port));
      stmaSource_Address:
        DoLog('#source_address: ' + TsgcSTUN_Attribute_SOURCE_ADDRESS
          (aMessage.Attributes.Items[i]).Address + ':' +
          IntToStr(TsgcSTUN_Attribute_SOURCE_ADDRESS(aMessage.Attributes.Items
          [i]).Port));
      stmaChanged_Address:
        DoLog('#changed_address: ' + TsgcSTUN_Attribute_CHANGED_ADDRESS
          (aMessage.Attributes.Items[i]).Address + ':' +
          IntToStr(TsgcSTUN_Attribute_CHANGED_ADDRESS(aMessage.Attributes.Items
          [i]).Port));
    end;
  end;
end;

573
COMPONENTS

STUN | TsgcSTUNServer
TsgcSTUNServer is the server that implements the STUN protocol and allows to process binding requests from
STUN clients.
 
The STUN server can be configured with or without Authentication, can verify Fingerprint Attribute, send an alter­
nate server and more.

Basic usage
Usually stun servers runs on UDP port 3478 and don't require authentication, so in order to configure a STUN serv­
er, set the listening port (by default 3478) and start the server.
 
Configure the server
• Port: the listening Server port, example: 3478
 
Set the property Active = True to start the STUN server.
 

oSTUN := TsgcSTUNServer.Create(nil);
oSTUN.Port := 3478;
oSTUN.Active := True;

Most common uses


• Configurations
• Long-Term Credentials
• Alternate Server
 

Properties
    Active: set the property to True to Start the STUN server and set to False to Stop the Server.
 
    Host: it's the IP Address or DNS name of STUN server.
 
    Port: it's the listening port of STUN server, by default 3478.
 
    IPVersion: it's the Family Address, by default IPv4.
 
    STUNOptions: here are defined the specific STUN options of server component
 
Fingerprint: if enabled, the message includes a fingerprint that aids to identify STUN messages from pack­
ets of other protocols when the two are multiplexed on the same transport address.
 
Software: if enabled, sends an attribute with the name of the software being used by the server.
 
Authentication: here you can configure if the server requires Authentication requests to send binding re­
sponses.
 
• Enabled: set to True if the server requires Authentication requests, by default false.
• LongTermCredentials: Enable if the server supports Long-Term credentials. The long-term creden­
tial mechanism relies on a long-term credential, in the form of a username and password that are
shared between client and server.

574
COMPONENTS

• Enabled: set to True if the server requires Long-Term credentials.


• Realm: the string of the realm sent to client.
• StaleNonce: time in seconds after the nonce is no longer valid.
 
BindingAttributes: when the server sends a successful response after a binding request, here you can cus­
tomize which attributes will be sent to the client.
 
• OtherAddress: if enabled and the server binds to more than one address, this attribute will be
sent with all other addresses except the default one.
• ResponseOrigin: is the Local IP of the server to send the response.
• SourceAddress:  is the Local IP of the server to send the response.
 
    LogFile: if enabled save stun messages to a specified log file, useful for debugging.
 
Enabled: if enabled every time a message is received and sent by server it will be saved on a file.
 
FileName: full path to the filename.
 
    NotifyEvents: defines which mode to notify the events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 

Events
    OnSTUNRequestAuthorization
 
This event is called when a binding request is received and requires authentication.
 
    OnSTUNRequestSuccess
 
When the server processes successfully a request binding, it sends a message with the binding properties
(IP Address, Port and family) and other attributes, this event is called before the message is sent to client.
 
    OnSTUNRequestError
 
When there is any error in the response sent by server, , this event is called before the message is sent to
client.
 
    OnSTUNException
 
This event is called when there is any exception processing the STUN protocol messages.

575
COMPONENTS

STUN Server | Long-Term Credentials


Usually STUN Servers are configured without Authentication, so any STUN client can send a binding request and
expect a response from server without Authentication.
 
sgcWebSockets STUN Server supports Long-Term Credentials, so you can configure TsgcSTUNServer to only al­
low binding requests with Long-Term credentials info.
 
To configure it, access to STUNOptions.Authorization property and enable it.
Then access to LongTermCredentials property and enabled it. By default, this type of authorization is already con­
figured with a Realm string and with a default StaleNonce value of 10 minutes (= 600 seconds).
 

oSTUN := TsgcSTUNServer.Create(nil);
oSTUN.Port := 3478;
oSTUN.STUNOptions.Authentication.Enabled := True;
oSTUN.STUNOptions.Authentication.LongTermCredentials.Enabled := True;
oSTUN.STUNOptions.Authentication.LongTermCredentials.Realm := 'sgcWebSockets';
oSTUN.STUNOptions.Authentication.LongTermCredentials.StaleNonce := 600;
oSTUN.Active := True;

procedure OnSTUNRequestAuthorization(Sender: TObject; const aRequest: TsgcSTUN_Message;


  const aUsername, aRealm: string; var Password: string);
begin
  if aUsername = 'my-user' then
    Password := 'my-password';
end;

576
COMPONENTS

STUN Server | Alternate Server


The alternate server represents an alternate transport address identifying a different STUN server that the STUN
client should try.
 
The STUN Server can be configured to send an alternate server as a response to a binding request, to configure
this behaviour, just access to STUNOptions.BindingAttributes.AlternateServer property and configure here the val­
ues required.
 

oSTUN := TsgcSTUNServer.Create(nil);
oSTUN.Port := 3478;
oSTUN.STUNOptions.BindingAttributes.AlternateServer.Enabled := True;
oSTUN.STUNOptions.BindingAttributes.AlternateServer.IPAddress := '80.54.54.1';
oSTUN.STUNOptions.BindingAttributes.AlternateServer.Port := 3478;
oSTUN.Active := True;

When the client receives the Alternate Server response attribute, it will try to send a request binding to the new
server.

577
COMPONENTS

TURN
Traversal Using Relays around NAT (TURN) protocol enables a server to relay data packets between devices.
 
If the public IP address of both the caller and callee is not discovered, TURN provides a fallback technique to relay
the call between endpoints.
 
Connecting a WebRTC session is an orchestrated effort done with the assistance of multiple WebRTC servers. The
NAT traversal servers in WebRTC are in charge of making sure the media gets properly connected. These servers
are STUN and TURN.
 

How WebRTC sessions connect


Directly
 
If both devices are on the local network, then there’s no special effort needed to be done to get them connected to
each other. If one device has the local IP address of the other device, then they can communicate with each other
directly.
 
 
Directly with public IP Address
 
Connecting WebRTC directly using public IP address obtained via STUN protocol.
 
 
Route through a TURN Server
 
When peers are behind a NAT and there are Firewalls, direct connection is not possible, so a TURN server is re­
quired to route the data between the peers.
 

Components
• TsgcTURNClient: it's the client component that implements the TURN protocol and allows to Allocate, cre­
ate permissions, Send Indications... to TURN Server.
 
• TsgcTURNServer: it's the server component that implements the TURN protocol.

578
COMPONENTS

TURN | TsgcTURNClient
TsgcTURNClient is the client that implements the TURN protocol and allows to send allocation requests to TURN
servers. The client inherits from STUN Client, so all methods supported by STUN client are already supported by
TURN Client.
 

Basic usage
Usually TURN servers runs on UDP port 3478 and don't require authentication, so in order to send a TURN re­
quest, fill the server properties to allow the client know where connect and Handle the events where the component
will receive the response from server.
 
Configure the server
• Host: the IP or DNS name of the server, example: turn.sgcwebsockets.com
• Port: the listening Server port, example: 3478
 
Call the method Allocate, to send a request to allocate an IP Address and a Port to the TURN server.
 
Handle the events
• If the server returns a successful response, the event OnTURNAllocateSuccess will be called and you can
access to the Allocation information reading the aAllocation object.
• If the server returns an error, the event OnSTUNResponseError will be called and you can access the Error
Code and Reason reading the aError object.
 

oTURN := TsgcTURNClient.Create(nil);
oTURN.Host := 'turn.sgcwebsockets.com';
oTURN.Port := 3478;
oTURN.Allocate;
 
procedure OnTURNAllocate(Sender: TObject; const aSocket: TsgcSocketConnection;
  const aMessage: TsgcSTUN_Message; const aAllocation: TsgcTURN_ResponseAllocation);
begin
  DoLog('Relayed IP: ' + aAllocation.RelayedIP + '. Relayed Port: ' + IntToStr(aAllocation.RelayedPort));
end;
 
procedure OnSTUNResponseError(Sender: TObject; const aMessage: TsgcSTUN_Message;
const aError: TsgcSTUN_ResponseError);
begin
  DoLog('Error: ' + IntToStr(aError.Code) + ' ' + aError.Reason);
end;

Most common uses


• Allocation
• Allocate IP Address
• Create Permissions
• Indications
• Send Indication
• Channels
• TURN Client Channels
 
 

TURN Relay Data


There are basically 2 ways to send data between peers:
 

579
COMPONENTS

1. Send Indications, which encapsulates the data in a STUN packet. Use the method SendIndication to send an
indication to other peer.
 
2. Use Channel Data, it's a more efficient way to send data between peers because the packet size is smaller than
indications. Use SendChannelData method to send a channel data to other peer.
 
When a TURN server receives a packet in a Relayed IP Address from an IP Address with an active permission, if
there is channel data bound to the peer IP Address, the TURN client will receive the data in the event OnTURN­
ChannelData. But if there is no channel, the TURN client will receive the data in the event OnTURNData.

Methods
Allocate
 
This method sends a request to the server to allocate an IP Address and a Port which will be used to relay date be­
tween the peers.
 
If the server can allocate successfully an IP Address and a Port, the event OnTURNAllocate event will be called. If
not, the OnSTUNRequestError event will be called.
 
The client saves in the Allocation property of the client, the data returned by server about the allocated IP Ad­
dress.
 
 
Refresh
 
If there is an active allocation, the client can refresh it sending a Refresh request.
 
This method has a parameter called Lifetime, if the value is zero, the allocation will expire immediately. If the value
is greater of zero, it means the number of seconds to expiry.
 
If the result is successful, the event OnTURNRefresh will be called.
 
 
CreatePermission
 
This method creates a new permission fo the IP Address set as an argument of the CreatePermission method. If
the permission already exists for this IP, it will be refreshed by the server.
 
If the result is successful, the event OnCreatePermission will be called.
 
 
SendIndication
 
This method sends a data to the peer identified as PeerIP and PeerPort. This method requires there is an active
permission for this IP in the TURN server.
 
 
ChannelBind
 
This method sends a request to the server to create a new channel to communicate with the peer identified as
PeerIP and PeerPort.
 
if the result is successful, the event OnChannelBind will be called. You can access to the channel-id assigned,
reading the parameter aChannelBind of the event.
 
 
SendChannelData
 
This method sends data to a peer using a ChannelId. This method requires the channel exists and is active.
 
 

580
COMPONENTS

Properties
    Host: it's the IP Address or DNS name of TURN server where the client will send a binding request.
 
    Port: it's the listening port of TURN server, by default 3478.
 
    IPVersion: it's the Family Address, by default IPv4.
 
    Transport: it's the transport used to connect to TURN server, by default UDP.
 
    STUNOptions: here are defined the specific STUN options of client component
 
Fingerprint: if enabled, the message includes a fingerprint that aids to identify STUN messages from pack­
ets of other protocols when the two are multiplexed on the same transport address.
 
Software: if enabled, sends an attribute with the name of the software being used by the client.
 
Authentication: some STUN servers requires that requests are authenticated.
 
• Credentials:  there are 2 types of Authentication: LongTermCredentials and ShortTermCredentials.
By default the requests are not authenticated
• Username: the string that identifies the user.
• Password: the secret string.
 
    TURNOptions: here are defined the specific TURN options of client component
 
Allocation: here are defined the Allocation properties
 
• Lifetime: default lifetime in seconds, by default 600 seconds.
 
Authentication: usually TURN servers are user protected.
 
• Credentials: by default Long-Term credentials is enabled
• Username: the string that identifies the user.
• Password: the secret string.
 
AutoRefresh: when a new allocation is created, requires to be refreshed in order to be used by the peers.
Here you can define which methods are automatically refreshed by the TURN Client Component.
 
• Allocations
• Channels
• Permissions
 
Fingerprint: if enabled, the message includes a fingerprint that aids to identify STUN messages from pack­
ets of other protocols when the two are multiplexed on the same transport address.
 
Software: if enabled, sends an attribute with the name of the software being used by the client.
 
 
 
    RetransmissionOptions: when messages are sent using UDP as transport, UDP doesn't includes a mechanism
to know if a message has arrived or not to other peer. This property allows to configure a mechanism to re-send
UDP messages if not arrived after a small time.
 
Enabled: if enabled, the message will be re-send until receives a confirmation or the maximum number of
retries has been reached.
 
RTO: retransmission time in milliseconds, by default 500ms. For example, assuming an RTO of 500 ms, re­
quests would be sent at times 0 ms, 500 ms, 1500 ms, 3500 ms, 7500 ms, 15500 ms, and 31500 ms.
 
MaxRetries: Max number of retries, by default 7.
 
    LogFile: if enabled save stun messages to a specified log file, useful for debugging. The access to log file is not
thread safe if it's accessed from several threads.
 

581
COMPONENTS

Enabled: if enabled every time a message is received and sent by client it will be saved on a file.
 
FileName: full path to the filename.
 
    NotifyEvents: defines which mode to notify WebSocket events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 
neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 

Events
The TURN client inherits from STUN Client the events: OnSTUNResponseSuccess, OnSTUNResponseError, On­
STUNException and OnSTUNBeforeSend.
 
Additionally, includes the following events to handle all TURN messages.
 
OnTURNAllocate
 
  This event is called after a successful IP Address allocation in the TURN server.
 
OnTURNCreatePermission
 
  This event is called after creating a new permission in the TURN server.
 
OnTURNRefresh
 
  This event is called after receiving a successful refresh response from the TURN Server.
 
OnTURNDataIndication
 
  The event is called when the client receives a DATA Indication from other peer.
 
OnTURNChannelBind
 
  This event is called when the server creates a new channel. Returns the new channel-id created.
 
OnTURNChannelData
 
  The event is called when the client receives new Data from a Channel previously created.
 
 

582
COMPONENTS

TURN Client | Allocate IP Address


TURN Protocol allows to use a Relayed IP Address to exchange data between peers that are behind NATs.
 
To create a new Relayed IP Address on a TURN server, the client must first call the method Allocate, this method
sends a Request to the TURN server to create a new Relayed IP Address, if the TURN server can create a new
Relayed IP Address, the client will receive a successful response. The client will be able to communicate with other
peers during the time defined in the Allocation's lifetime.
 

oTURN := TsgcTURNClient.Create(nil);
oTURN.Host := 'turn.sgcwebsockets.com';
oTURN.Port := 3478;
oTURN.Allocate();

procedure OnTURNAllocate(Sender: TObject; const aSocket: TsgcSocketConnection; const


aMessage: TsgcSTUN_Message; const aAllocation: TsgcTURN_ResponseAllocation);
begin
  DoLog('Relayed IP: ' + aAllocation.RelayedIP + '. Relayed Port: ' + IntToStr(aAllocation.RelayedPort));
end;

 
procedure OnSTUNResponseError(Sender: TObject; const aMessage: TsgcSTUN_Message;
const aError: TsgcSTUN_ResponseError);
begin
  DoLog('Error: ' + IntToStr(aError.Code) + ' ' + aError.Reason);
end;

The lifetime can be updated to avoid expiration using the method Refresh. The Lifetime is the number of seconds
to expire. If the value is zero the Allocation will be deleted.
 

oTURN.Refresh(600);

583
COMPONENTS

TURN Client | Create Permissions


When a new Allocation is created in a TURN server, this allocation cannot process any incoming packet from other
peers if has no permissions. So, in order to allow other peers to communicate using a Relayed IP Address, first the
TURN Client must create permissions for the IP Addresses that are allowed to exchange Data.
 
To Create a new Permission, just call the method CreatePermission and pass as a parameter the IP Address of
the peer. If the Peer IP already exists on the TURN server, it will be refreshed, if not, it will be created. Permissions
expire after 5 minutes unless are refreshed.
 
The TURN client, only allows to call the method CreatePermission if exists an active allocation.
 
If the permission is created successfully, the event OnTURNCreatePermission is called.
 

oTURN.CreatePermission('80.147.23.157');

procedure OnTURNCreatePermission(Sender: TObject; const aSocket: TsgcSocketConnection;


  const aMessage: TsgcSTUN_Message; const aCreatePermission: TsgcTURN_ResponseCreatePermission);
begin
  DoLog('#Create Permission: ' + aCreatePermission.IPAddresses.Text);
end;

584
COMPONENTS

TURN Client | Send Indication


TURN Protocol supports 2 mechanisms for sending and receiving data from peers, one of them is Send and Data
mechanisms.
 
The TURN client can use the SendIndication method to send data to the server for relaying to a peer. The TURN
client must ensure that there is a permission for the Peer IP Address where the Send Indication will be sent.
 
The responses to a SendIndication method, are received OnTURNDataIndication event.
 

oTURN.SendIndication('80.147.23.157', 5000, 'random data');

procedure OnTURNDataIndication(Sender: TObject; const aSocket: TsgcSocketConnection;


  const aMessage: TsgcSTUN_Message; const aDataIndication: TsgcTURN_ResponseDataIndication);
begin
  DoLog('#Data Indication: [' + aDataIndication.PeerIP + ':' + IntToStr(aDataIndication.PeerPort) + '] ' +
    sgcGetStringFromBytes(aDataIndication.Data));
end;

585
COMPONENTS

TURN Client | Channels


Channels provide a way for the TURN Client and Server to send application data using ChannelData messages,
which have less overhead than Send and Data Indications.
 
Before use ChannelData messages to exchange data between peers, the TURN client must create a new channel,
to do this, just call the method ChannelBind passing the Peer IP Address and Port as parameters.
 
If the TURN server can bind a new channel, the TURN client will receive a successful response OnTURNChannel­
Bind event.
 

oTURN.ChannelBind('80.147.23.157', 5000);

procedure OnTURNChannelBind(Sender: TObject; const aSocket: TsgcSocketConnection;


  const aMessage: TsgcSTUN_Message; const aChannelBind: TsgcTURN_ResponseChannelBind);
begin
  DoLog('#Channel Bind: ' + IntToStr(aChannelBind.Channel));
end;

A channel binding lasts for 10 minutes unless refreshed. To refresh a channel just call ChannelBind method again.
 
When the TURN client receives a new ChannelMessage, the event OnTURNChannelData is called.
 

procedure OnTURNChannelData(Sender: TObject; const aSocket: TsgcSocketConnection;


  const aChannelData: TsgcTURNChannelData);
begin
  DoLog('#Channel Data: [' + IntToStr(aChannelData.ChannelID) + '] ' +
    sgcGetStringFromBytes(aChannelData.Data));
end;

586
COMPONENTS

TURN | TsgcTURNServer
TsgcTURNServer is the server that implements the TURN protocol and allows to process requests from TURN
clients. The component inherits from TsgcSTUNServer, so all methods and properties are available on Tsgc­
TURNServer.
 
TURN Server supports Long-Term Authentication, Allocation, Permissions, Channel Data and more.
 

Basic usage
Usually TURN servers runs on UDP port 3478 and require Long-Term credentials, so in order to configure a TURN
server, set the listening port (by default 3478) and start the server.
 
Configure the server
• Port: the listening Server port, example: 3478
• Define the Long-Term Credentials properties in TURNOptions.Authentication.LongTermCredentials
• Handle the OnSTUNRequestAuthorization to set the password when a TURN client sends a request to
TURN Server.
 
Set the property Active = True to start the STUN server.
 

oTURN := TsgcTURNServer.Create(nil);
oTURN.Port := 3478;
oTURN.TURNOptions.Authentication.Enabled := True;
oTURN.TURNOptions.Authentication.LongTermCredentials.Enabled := True;
oTURN.TURNOptions.Authentication.LongTermCredentials.Realm := 'esegece.com';
oTURN.Active := True;

procedure OnSTUNRequestAuthorization(Sender: TObject; const aRequest: TsgcSTUN_Message;


  const aUsername, aRealm: string; var Password: string);
begin
  if (aUsername = 'user') and (aRealm = 'esegece.com') then
    Password := 'password';
end;

Most common uses


• Configurations
• Long-Term Credentials
• Allocations
• Allocations
 
 

Properties
    Active: set the property to True to Start the TURN server and set to False to Stop the Server.
 
    Host: it's the IP Address or DNS name of TURN server.
 
    Port: it's the listening port of TURN server, by default 3478.
 
    IPVersion: it's the Family Address, by default IPv4.
 
    STUNOptions: here are defined the specific options for STUN Requests
 
Fingerprint: if enabled, the message includes a fingerprint that aids to identify STUN messages from pack­
ets of other protocols when the two are multiplexed on the same transport address.
 

587
COMPONENTS

Software: if enabled, sends an attribute with the name of the software being used by the server.
 
Authentication: here you can configure if the server requires Authentication requests to send binding re­
sponses.
 
• Enabled: set to True if the server requires Authentication requests, by default false.
• LongTermCredentials: Enable if the server supports Long-Term credentials. The long-term creden­
tial mechanism relies on a long-term credential, in the form of a username and password that are
shared between client and server.
• Enabled: set to True if the server requires Long-Term credentials.
• Realm: the string of the realm sent to client.
• StaleNonce: time in seconds after the nonce is no longer valid.
 
BindingAttributes: when the server sends a successful response after a binding request, here you can cus­
tomize which attributes will be sent to the client.
 
• OtherAddress: if enabled and the server binds to more than one address, this attribute will be
sent with all other addresses except the default one.
• ResponseOrigin: is the Local IP of the server to send the response.
• SourceAddress:  is the Local IP of the server to send the response.
 
 
 
    TURNOptions: here are defined the specific options for TURN Requests
 
Fingerprint: if enabled, the message includes a fingerprint that aids to identify TURN messages from pack­
ets of other protocols when the two are multiplexed on the same transport address.
 
Software: if enabled, sends an attribute with the name of the software being used by the server.
 
Allocation: when a new allocation is created, the server takes from this property the default values.
 
• DefaultLifeTime: value in seconds of default LifeTime.
• MaxLifeTime: max value of LifeTime, if a TURN client requests a value greater of this value, the val­
ue returned will be the MaxLifeTime.
• MaxUserAllocations: max number of allocations.
• MinPort: Minimum range port of allocations.
• MaxPort: Maximum range port of allocations.
• RelayIP: if defined, this will be the Relayed IP Address.
 
Authentication: usually TURN servers require Long-Term Credentials authentication.
 
• Enabled: set to True if the server requires Authentication requests, by default false.
• LongTermCredentials: Enable if the server supports Long-Term credentials. The long-term creden­
tial mechanism relies on a long-term credential, in the form of a username and password that are
shared between client and server.
• Enabled: set to True if the server requires Long-Term credentials.
• Realm: the string of the realm sent to client.
• StaleNonce: time in seconds after the nonce is no longer valid.
 
 
    LogFile: if enabled save stun messages to a specified log file, useful for debugging.
 
Enabled: if enabled every time a message is received and sent by server it will be saved on a file.
 
FileName: full path to the filename.
 
    NotifyEvents: defines which mode to notify the events.
 
neAsynchronous: this is the default mode, notify threaded events on asynchronous mode, adds events to a
queue that are synchronized with the main thread asynchronously.
 
neSynchronous: if this mode is selected, notify threaded events on synchronous mode, needs to synchro­
nize with the main thread to notify these events.
 

588
COMPONENTS

neNoSync: there is no synchronization with the main thread, if you need to access to controls that are not
thread-safe, you need to implement your own synchronization methods.
 

Events
The TURN server inherits from STUN Server the events: OnSTUNRequestAuthorization, OnSTUNRequestSuc­
cess, OnSTUNRequestError and OnSTUNException.
 
Additionally, includes the following events to handle all TURN messages.
 
    OnTURNBeforeAllocate
 
The event is called before create a new Allocation. It provides the IP Address and Port used to Relay Data,
you can reject if don't want to accept the Allocation.
 
    OnTURNCreateAllocation
 
The event is called after creating successfully an Allocation.
 
    OnTURNDeleteAllocation
 
The event is called after remove an already created Allocation.
 
    OnTURNMessageDiscarded
 
The event is called when a message received by server is discarded.
 
    OnTURNChannelDataDiscarded
 
The event is called when a Channel Data message is discarded.
 
 

589
COMPONENTS

TURN Server | Long Term Credentials


Usually TURN Servers are configured WITH Authentication for TURN requests and without Authentication for
STUN requests.
 
sgcWebSockets TURN Server supports Long-Term Credentials, so you can configure TsgcTURNServer to only al­
low requests with Long-Term credentials info.
 
To configure it, access to TURNOptions.Authorization property and enable it.
Then access to LongTermCredentials property and enabled it. By default, this type of authorization is already con­
figured with a Realm string and with a default StaleNonce value of 10 minutes (= 600 seconds).
 

oTURN := TsgcTURNServer.Create(nil);
oTURN.Port := 3478;
oTURN.STUNOptions.Authentication.Enabled := False;
oTURN.TURNOptions.Authentication.Enabled := True;
oTURN.TURNOptions.Authentication.LongTermCredentials.Enabled := True;
oTURN.TURNOptions.Authentication.LongTermCredentials.Realm := 'sgcWebSockets';
oTURN.TURNOptions.Authentication.LongTermCredentials.StaleNonce := 600;
oTURN.Active := True;

procedure OnSTUNRequestAuthorization(Sender: TObject; const aRequest: TsgcSTUN_Message;


  const aUsername, aRealm: string; var Password: string);
begin
  if (aUsername = 'my-user') and (aRealm = 'sgcWebSockets') then
    Password := 'my-password';
end;

590
COMPONENTS

TURN Server | Allocations


All TURN operations revolve around allocations and all TURN messages are associated with an Allocation. An allo­
cation consists of:
 
• The relayed transport address
• The 5-Tuple: client's IP Address, client's IP port, server IP address, server port and transport protocol.
• The authentication information.
• The time-to-expiry for each relayed transport address.
• A list of permissions for each relayed transport address.
• A list of channels bindings for each relayed transport address.
 
When a TURN client sends an Allocate request, this TURN message is processed by server and tries to create a
new Relayed Transport Address. By default, if there is any available UDP port, it will create a new Relayed Ad­
dress, but you can use OnTURNBeforeAllocate event to reject a new Allocation request.
 

procedure OnTURNBeforeAllocate(Sender: TObject; const aSocket: TsgcSocketConnection;


  const aIP: string; aPort: Word; var Reject: Boolean);
begin
  if not (your own rules) then
Reject := false;
end;

If the process continues, the server creates a new allocation and the event OnTURNCreateAllocation is called.
This event provides information about the Allocation through the class TsgcTURNAllocationItem.
 

procedure OnTURNCreateAllocation(Sender: TObject; const aSocket: TsgcSocketConnection;


  const Allocation: TsgcTURNAllocationItem);
begin
  DoLog('New Allocation: ' + Allocation.RelayIP + ':' + IntToStr(Allocation.RelayPort));
end;

 
When the Allocation expires or is deleted receiving a Refresh Request from client with a lifetime of zero, the event
OnTURNDeleteAllocation event is fired.
 

procedure OnTURNDeleteAllocation(Sender: TObject; const aSocket: TsgcSocketConnection;


  const Allocation: TsgcTURNAllocationItem);
begin
  DoLog('Allocation Deleted: ' + Allocation.RelayIP + ':' + IntToStr(Allocation.RelayPort));
end;

591
COMPONENTS

Datasnap
By default, DataSnap uses TIdHttpWebBrokerBridge as server to handle HTTP requests. But you can expand the
possibilities of your DataSnap application replacing this server for other with support for more protocols and with
much better performance, taking advantage of latest protocols like HTTP/2 which improves the server performance,
IOCP which allows to handle much more connections and more....

Servers

Main
Server Description
Features
Based on In­
Web­ dy library,
Socket supports
Protocol WebSocket
HTTP 1.* and HTTP
TsgcWSHTTPWebBrokerBridgeServer
Protocol protocols on
XHR Pro­ the same
tocol port. IOCP
IOCP can be en­
abled too.
Web­ Based on In­
Socket dy library,
Protocol supports
HTTP 1.* WebSocket
Protocol and HTTP/2
TsgcWSHTTP2WebBrokerBridgeServer
HTTP/2 protocols on
Protocol the same
XHR Pro­ port. IOCP
tocol can be en­
IOCP abled too.
Based on
HTTP.SYS
Microsoft
Web­
HTTP API,
Socket
supports
Protocol
WebSocket
HTTP 1.*
and HTTP/2
Protocol
TsgcWSServer_HTTPAPI_WebBrokerBridge protocols on
HTTP/2
the same
Protocol
port. IOCP is
XHR Pro­
used by de­
tocol
fault. Recom­
IOCP
mended for
best perfor­
mance.
 
 

592
COMPONENTS

TsgcWSHTTPWebBrokerBridgeServer
TsgcWSHTTPWebBrokerBridgeServer make use of TIdHttpWebBrokerBridge as server base and is useful if
you want to use a single server for DataSnap, HTTP and WebSocket connections.
 
TsgcWSHTTPWebBrokerBridgeServer inherits from TsgcWebSocketHTTPServer, so you can refer to this serv­
er.
 
Follow next steps to replace TIdHttpWebBrokerBridge for TsgcWSHTTPWebBrokerBridgeServer :
 
1. Create a new instance of TsgcWSHTTPWebBrokerBridgeServer.
 
2. Replace all calls to TIdHttpWebBrokerBridge for TsgcWSHTTPWebBrokerBridgeServer.
 
3. To Handle WebSocket connections just refer to TsgcWebSocketHTTPServer.
 

Configuration
The Datasnap components are only located in Source folder, you won't find in the compiled folders because
these objects are not included in sgcWebSockets package, so you must create in runtime.
Just add the required files to your project or set your path to the Source folder of sgcWebSockets package. Files re­
quired:
 
• sgcWebSocket_Server_WebBrokerBridge
 

Events

FServer := TsgcWSHTTPWebBrokerBridgeServer.Create(Self);
FServer.OnCommandRequest := OnCommandRequestEvent;
FServer.OnCommandGet := OnCommandGetevent;
  
procedure OnCommandRequestEvent(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo; var aHandled: Boolean);
begin
  if ARequestInfo.Document = '/test.html' then
    aHandled := True;
end;
 
procedure OnCommandGetevent(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document = '/test.html' then
  begin
    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentText := 'hello all';
  end;
end;

593
COMPONENTS

TsgcWSHTTP2WebBrokerBridgeServer
TsgcWSHTTP2WebBrokerBridgeServer use TsgcWebSocketHTTPServer with HTTP/2 protocol enabled as
server base and is useful if you want to use a single server for DataSnap, HTTP/2 and WebSocket connections.
 
TsgcWSHTTP2WebBrokerBridgeServer inherits from TsgcWebSocketHTTPServer, so you can refer to this
server.
 
Follow next steps to replace TIdHttpWebBrokerBridge for TsgcWSHTTP2WebBrokerBridgeServer :
 
1. Create a new instance of TsgcWSHTTP2WebBrokerBridgeServer.
 
2. Replace all calls to TIdHttpWebBrokerBridge for TsgcWSHTTP2WebBrokerBridgeServer.
 
3. To Handle WebSocket connections just refer to TsgcWebSocketHTTPServer.
 

Configuration
The Datasnap components are only located in Source folder, you won't find in the compiled folders because
these objects are not included in sgcWebSockets package, so you must create in runtime.
Just add the required files to your project or set your path to the Source folder of sgcWebSockets package. Files re­
quired:
 
• sgcWebSocket_Server_Base_WebBrokerBridge
• sgcWebSocket_Server_WebBrokerBridge_HTTP2

Events

FServer := TsgcWSHTTP2WebBrokerBridgeServer.Create(Self);
FServer.OnCommandRequest := OnCommandRequestEvent;
FServer.OnCommandGet := OnCommandGetevent;
  
procedure OnCommandRequestEvent(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo; var aHandled: Boolean);
begin
  if ARequestInfo.Document = '/test.html' then
    aHandled := True;
end;
 
procedure OnCommandGetevent(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document = '/test.html' then
  begin
    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentText := 'hello all';
  end;
end;

594
COMPONENTS

TsgcWSServer_HTTPAPI_WebBrokerBridge
TsgcWSServer_HTTPAPI_WebBrokerBridge use TsgcWebSocketServer_HTTPAPI with HTTP/2 protocol en­
abled as server base and is useful if you want to use a single server for DataSnap, HTTP/2 and WebSocket con­
nections.
 
TsgcWSServer_HTTPAPI_WebBrokerBridge inherits from TsgcWebSocketServer_HTTPAPI, so you can refer
to this server.
 
Follow next steps to replace TIdHttpWebBrokerBridge for TsgcWSServer_HTTPAPI_WebBrokerBridge:
 
1. Create a new instance of TsgcWSServer_HTTPAPI_WebBrokerBridge.
 
2. Replace all calls to TIdHttpWebBrokerBridge for TsgcWSServer_HTTPAPI_WebBrokerBridge.
 
3. To Handle WebSocket connections just refer to TsgcWSServer_HTTPAPI_WebBrokerBridge.
 

Configuration
The Datasnap components are only located in Source folder, you won't find in the compiled folders because
these objects are not included in sgcWebSockets package, so you must create in runtime.
Just add the required files to your project or set your path to the Source folder of sgcWebSockets package. Files re­
quired:
 
• sgcWebSocket_Server_Base_WebBrokerBridge
• sgcWebSocket_Server_HTTPAPI_WebBrokerBridge

Events

FServer := TsgcWSServer_HTTPAPI_WebBrokerBridge.Create(Self);
FServer.OnCommandRequest := OnCommandRequestEvent;
FServer.OnMessage := OnWebSocketMessage;
  
procedure OnCommandRequestEvent(aConnection : TsgcWSConnection_HTTPAPI;
const aRequestInfo: THttpServerRequest; var aResponseInfo: THttpServerResponse; var aHandled: Boolean);
begin
  if ARequestInfo.Document = '/test.html' then
  begin
    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentText := '... body ...

';  
    aHandled := True;
  end;
end;
procedure OnWebSocketMessage(aConnection: TsgcWSConnection; const aText: string);
begin
  aConnection.WriteData(aText);
end;

595
DEMOS

Demos | Server Chat


This demo shows how build a Server Chat using TsgcWebSocketHTTPServer and WebSockets as communication
protocol.
Every time a new peer sends a message, the server reads the message and broadcast the message to all connect­
ed clients.
 

Start Server
Before start the server, you must configure it to set the listening port, if use a secure connection or not...
 
• First I create a new instance of TsgcWebSocketHTTPServer.
• If Server will use secure connections, it needs a PEM certificate, just set where is located this certificate and
the listening port for SSL You can configure the TLS version and the OpenSSL API (if needed)
 

  WSServer.HTTP2Options.Enabled := chkHTTP2.Checked;
  if WSServer.HTTP2Options.Enabled then
  begin
    WSServer.SSLOptions.OpenSSL_Options.APIVersion := oslAPI_1_1;
    WSServer.SSLOptions.Version := tls1_3;
  end
  else
  begin
    case cboOpenSSLAPI.ItemIndex of
      0: WSServer.SSLOptions.OpenSSL_Options.APIVersion := oslAPI_1_0;
      1: WSServer.SSLOptions.OpenSSL_Options.APIVersion := oslAPI_1_1;
    end;
    case cboTLSVersion.ItemIndex of
      0: WSServer.SSLOptions.Version := tlsUndefined;
      1: WSServer.SSLOptions.Version := tls1_0;
      2: WSServer.SSLOptions.Version := tls1_1;
      3: WSServer.SSLOptions.Version := tls1_2;
      4: WSServer.SSLOptions.Version := tls1_3;
    end;
  end;

• By default, if you start the server, it will listening on ALL IPs of listening port, so it's recommended use the
binding property to only listen on 1 specific IP.
 

With WSServer.Bindings.Add do
begin
  Port := StrToInt(txtDefaultPort.Text);
  IP := txtHost.Text;
end;

 
• Once configured all options, call Server.Active = true to start the server.
 

Events Configuration
• Use OnConnect and OnDisconnect events to know when a client connects to server.
• Messages sent from client to server are received OnMessage event, so use this event handler to broad­
cast the message received to all clients
 

procedure TfrmServerChat.WSServerMessage(Connection: TsgcWSConnection; const Text: string);


begin
  WSServer.Broadcast(Text);
end;

596
DEMOS

Dispatch HTTP Requests


WebSocket HTTP Server allows to handle WebSocket and HTTP Protocols on the same listening port, so a web-
browser can request a web page to access your server. OnCommandGet is the event used to read the HTTP Re­
quest and send the HTTP Responses.
 
Use ARequestInfo parameter to read the HTTP Request and AResponseInfo to write the HTTP Response.
 
Basically, use the ARequestInfo.Document to read which document is requesting the client and send a response
using the following properties: ResponseNo, ContentType and ContentText.
 
Example: a client request document '/jquery.js'

procedure TfrmServerChat.WSServerCommandGet(AContext: TIdContext; ARequestInfo:


    TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document = '/jquery.js' then
  begin
    AResponseInfo.ContentText := pageJQuery.Content;
    AResponseInfo.ContentType := 'text/javascript';
    AResponseInfo.ResponseNo := 200;
  end;
end;

597
DEMOS

Client Chat
This demo shows how build a client chat, using TsgcWebSocketClient, which connects to a WebSocket Server,
sends a message and this message is received by all connected clients.
 

Connect to Server
• First create a new instance of TsgcWebSocketClient.
• Then configure the server Host and Port.
• If client uses a secure connection, configure the TLSOptions property of the component.
 

  if chkTLS.Checked then


    WSClient.Port := StrToInt(txtSSLPort.Text)
  else
    WSClient.Port := StrToInt(txtDefaultPort.Text);
  WSClient.Host := txtHost.Text;
  case cboOpenSSLAPI.ItemIndex of
    0: WSClient.TLSOptions.OpenSSL_Options.APIVersion := oslAPI_1_0;
    1: WSClient.TLSOptions.OpenSSL_Options.APIVersion := oslAPI_1_1;
  end;
  case cboTLSVersion.ItemIndex of
    0: WSClient.TLSOptions.Version := tlsUndefined;
    1: WSClient.TLSOptions.Version := tls1_0;
    2: WSClient.TLSOptions.Version := tls1_1;
    3: WSClient.TLSOptions.Version := tls1_2;
    4: WSClient.TLSOptions.Version := tls1_3;
  end;
  WSClient.TLS := chkTLS.Checked;

• Once all options can be configured, set Client.Active = true to connect to server.
 

Send Message To Server


• To send a message to server, use WriteData method, send any Text message and server will send as a re­
sponse the same message.
 

WSClient.WriteData(txtName.Text + ': ' + txtMessage.Text);

Receive Messages from Server


• Every time a new Text message is received by client, OnMessage event is fired.
 

procedure TfrmClientChat.WSClientMessage(Connection: TsgcWSConnection; const


    Text: string);
begin
  memoLog.Lines.Add(Text);
end;

598
DEMOS

Demos | Client
This demo shows how build a websocket client, using TsgcWebSocketClient.
 

Connect to Server
• First create a new instance of TsgcWebSocketClient.
• Then configure the server Host and Port.
• By default the client will connect using WebSocket protocol. But you can configure the client to connect us­
ing plain TCP protocol. Just set Specifications.RFC6455 = false, and the client will use plain TCP protocol
instead of WebSocket protocol. You can read more about TCP Connections.
 

WSClient.Host := txtHost.Text;
WSClient.Port := StrToInt(txtPort.Text);
WSClient.Options.Parameters := txtParameters.Text;
WSClient.TLS := chkTLS.Checked;
WSClient.Specifications.RFC6455 := chkOverWebSocket.Checked;
WSClient.Proxy.Enabled := chkProxy.Checked;
WSClient.Proxy.Username := txtProxyUsername.Text;
WSClient.Proxy.Password := txtProxyPassword.Text;
WSClient.Proxy.Host := txtProxyHost.Text;
if txtProxyPort.Text  '' then
WSClient.Proxy.Port := StrToInt(txtProxyPort.Text);
WSClient.Extensions.PerMessage_Deflate.Enabled := chkCompressed.Checked;
// ... active
WSClient.Active := True;

Client Events
Use the following events to control the client flow: when connects, disconnects, receives a message, an error is de­
tected...
 

procedure TfrmWebSocketClient.WSClientConnect(Connection: TsgcWSConnection);


begin
  DoLog('#connected');
end;
procedure TfrmWebSocketClient.WSClientDisconnect(Connection: TsgcWSConnection;
  Code: Integer);
begin
  DoLog('#disconnected');
end;
procedure TfrmWebSocketClient.WSClientError(Connection: TsgcWSConnection;
  const Error: string);
begin
  DoLog('#error: ' + Error);
end;
procedure TfrmWebSocketClient.WSClientException(Connection: TsgcWSConnection;
  E: Exception);
begin
  DoLog('#exception: ' + E.Message);
end;
procedure TfrmWebSocketClient.WSClientMessage(Connection: TsgcWSConnection;
  const Text: string);
begin
  DoLog(Text);
end;

599
DEMOS

Demos | Client MQTT


This demo shows how connect to a MQTT broker server. Requires a TsgcWebSocketClient to handle WebSocket /
TCP protocols.
 

Configuration
• First create a new TsgcWebSocketClient instance, check the Client Demo.
• Then, create a new instance of TsgcWSPClient_MQTT.
• After that, you must assign the MQTT Protocol to WebSocket client and configure the connection options in
WebSocket client.
 

  MQTT.Client := WSClient;
  txtParameters.Text := '/';
  chkTLS.Checked := False;
  MQTT.Authentication.Enabled := False;
  MQTT.Authentication.Username := '';
  MQTT.Authentication.Password := '';
  MQTT.MQTTVersion := mqtt311;
  case aItemIndex of
    0: // esegece.com
      begin
        txtHost.Text := 'www.esegece.com';
        txtPort.Text := '15675';
        txtParameters.Text := '/ws';
        MQTT.Authentication.Enabled := True;
        MQTT.Authentication.Username := 'sgc';
        MQTT.Authentication.Password := 'sgc';
      end;
    1: // test.mosquitto.org
      begin
        txtHost.Text := 'test.mosquitto.org';
        txtPort.Text := '1883';
        chkTLS.Checked := False;
        chkOverWebSocket.Checked := False;
      end;
    2: // mqtt.fluux.io
      begin
        txtHost.Text := 'mqtt.fluux.io';
        txtPort.Text := '1883';
        chkTLS.Checked := False;
        chkOverWebSocket.Checked := False;
        MQTT.MQTTVersion := mqtt5;
      end;
    3: // broker.hivemq.com
      begin
        txtHost.Text := 'broker.mqttdashboard.com';
        txtPort.Text := '8000';
        txtParameters.Text := '/mqtt';
        chkTLS.Checked := False;
        chkOverWebSocket.Checked := True;
        MQTT.MQTTVersion := mqtt5;
      end;
  end;

MQTT Events
The connection flow is controlled by MQTT Client component, so you must handle the MQTT events to know when
it's connected to broker, when a new message is published, when is disconnected...
 

procedure TfrmWebSocketClient.MQTTMQTTConnect(Connection: TsgcWSConnection;


    const Session: Boolean; const ReasonCode: Integer; const ReasonName:
    string; const ConnectProperties: TsgcWSMQTTCONNACKProperties);
begin
  DoLog('#connected');
  chkTLS.Enabled := False;
  chkCompressed.Enabled := False;
  if FMQTTSubscribeTopic  '' then

600
DEMOS

  begin
    MQTT.Subscribe(FMQTTSubscribeTopic);
    FMQTTSubscribeTopic := '';
  end;
end;

procedure TfrmWebSocketClient.MQTTMQTTPublish(Connection: TsgcWSConnection;


    aTopic, aText: string; PublishProperties: TsgcWSMQTTPublishProperties);
begin
  DoLog(aTopic + ': ' + aText);
end;

procedure TfrmWebSocketClient.MQTTMQTTSubscribe(Connection: TsgcWSConnection;


    aPacketIdentifier: Word; aCodes: TsgcWSSUBACKS; SubscribeProperties:
    TsgcWSMQTTSUBACKProperties);
begin
  DoLog('#Subscribe: ' + IntToStr(aPacketIdentifier));
end;

procedure TfrmWebSocketClient.MQTTMQTTDisconnect(Connection: TsgcWSConnection;


    ReasonCode: Integer; const ReasonName: string; DisconnectProperties:
    TsgcWSMQTTDISCONNECTProperties);
begin
  DoLog('#disconnected');
  chkTLS.Enabled := True;
  chkCompressed.Enabled := True;
end;

601
DEMOS

Demos | Client SocketIO


This demo shows how connect to a Socket.IO Server. Requires a TsgcWebSocketClient to handle WebSocket /
TCP protocols.
 

Configuration
• First create a new TsgcWebSocketClient instance, check the Client Demo.
• Then, create a new instance of TsgcWSAPI_SocketIO.
• After that, you must assign the Socket.IO API to WebSocket client and configure the connection options in
WebSocket client.
 

SOCKETIO.Client := WSClient;
WSClient.Host := 'socketio-chat-h9jt.herokuapp.com';
WSClient.Port := 443;
WSClient.Options.Parameters := '/';
WSClient.Specifications.RFC6455 := True;
WSClient.TLS := True;

Send Messages
Socket.IO uses TsgcWebSocketClient to send messages to server, so just call WriteData and pass as a parame­
ter the JSON message to socket.io server
 

WSClient.WriteData('42["new message", "' +  txtSocketIOMessage.Text + '"]');

Receive Messages
The messages received as the flow of connection is handled by TsgcWebSocketClient, so use this component to
read the messages sent from server and to know if connection is active or not.
 

procedure TfrmWebSocketClient.WSClientMessage(Connection: TsgcWSConnection;


  const Text: string);
begin
  DoLog(Text);
end;

602
DEMOS

Demos | Server Monitor


This demo show how update 3 HTML Monitors using WebSocket as protocol. Server has an internal timer that up­
dates randomly the values of the gauges and updates the value using a websocket message. This message is read
by javascript client and updates the value of the Gauge.
 

Configuration
• First create a new TsgcWebSocketServer instance, check the Server Chat Demo.
• Then Create a new Timer and every 500 milliseconds update the values of: memory, network or cpu. Send
the update to all clients connected.
• In Javascript client, read the message sent by server and update the value of the gauge.
 

<pre><code>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Server Monitor Demo</title>
<script src="http://127.0.0.1:5413/sgcWebSockets.js"></script>
<script src="http://127.0.0.1:5413/esegece.com.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<style>
#status {
padding: 5px;
color: #fff;
background: #ccc;
}
#status.fail {
          background: #c00;
}
#status.offline {
          background: #c00;
}
#status.online {
          background: #0c0;
}
</style>
<script type='text/javascript'>
          var vMemory;
          var vCpu;
          var vNetwork;
          var chart;
          var data;
          var options;
          var ws;
          
          vMemory=30;
          vCpu=55;
          vNetwork=68;
      google.load('visualization', '1', {packages:['gauge']});
          google.setOnLoadCallback(drawChart);
      function drawChart() {
        data = google.visualization.arrayToDataTable([
          ['Label', 'Value'],
          ['Memory', vMemory],
          ['CPU', vCpu],
          ['Network', vNetwork]
        ]);
        options = {
          width: 400, height: 120,
          redFrom: 90, redTo: 100,
          yellowFrom:75, yellowTo: 90,
          minorTicks: 5
        };
        chart = new google.visualization.Gauge(document.getElementById('chart_div'));
        chart.draw(data, options);
}

function updateChart() {

603
DEMOS

data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Memory', vMemory],
['CPU', vCpu],
['Network', vNetwork]
]);
chart.draw(data, options);
}

function subscribe(Channel)
{
          if (document.getElementById(Channel).checked) {            
ws.subscribe(Channel);
          } else {
ws.unsubscribe(Channel);
          }
}

function wsmonitor()
{
          if ("WebSocket" in window)
          {
                  ws = new sgcws("ws://127.0.0.1:5413");
                  ws.on('open', function(evt){                  
document.getElementById('status').innerHTML = "Socket Open";
document.getElementById('status').className = "online";
ws.subscribe("memory");
ws.subscribe("cpu");
ws.subscribe("network");
}
                  );
                  ws.on('close', function(evt){
document.getElementById('status').innerHTML = "Socket Closed";
document.getElementById('status').className = "offline";
                        }                  
                  );
                  ws.on('sgcevent', function(evt){
if (evt.channel == "memory") {
                          vMemory = parseInt(evt.message);
} else if (evt.channel == "cpu") {
                          vCpu = parseInt(evt.message);
} else if (evt.channel == "network") {
                          vNetwork = parseInt(evt.message);
}
updateChart();
}
                  );
                  ws.on('error', function(evt){
document.getElementById('status').innerHTML = "Socket Error";
document.getElementById('status').className = "fail";
                        }                  
                  );
          }
}
</script>
</head>
<body>
<div data-role="page" id="wsdemo_monitor">
<div data-role="header" data-theme="b">
<h1>Server Monitor</h1>
<a href="#home" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-left jqm-home
</div><!-- /header -->
<div data-role="content">
<h2>Press Start to Get Monitor Data</h2>
<p id="status" classname="success"></p>
<h4>Select which data you want to receive: Memory - CPU - Network</h4>
<a href="javascript:wsmonitor()" data-role="button" data-inline="true">Start</a>
<div id='chart_div'></div>
<div data-role="fieldcontain">
                    <fieldset data-role="controlgroup" data-type="horizontal">
                            <input type="checkbox" name="memory" id="memory" class="custom" checked="True" onclick
<label for="memory">Memory</label>
<input type="checkbox" name="cpu" id="cpu" class="custom" checked="True" onclick=
<label for="cpu">CPU</label>
<input type="checkbox" name="network" id="network" class="custom" checked="True"
<label for="network">Network</label>    
                    </fieldset>
</div>
</div><!-- /content -->
<div data-role="footer" class="footer-docs" data-theme="c">
<p>&copy; 2020 eSeGeCe.com</p>
</div>
</div><!-- /page -->
</body>
</html>
</code></pre>

604
DEMOS

605
DEMOS

Demos | Server Snapshots


This demo show how send images from server to client and how all clients receive the same image using broad­
cast method of server component.
 

Configuration
• First create a new TsgcWebSocketHTTPServer instance, check the Server Chat Demo.
• Enable compression to send less bytes when message is transmitted to clients
 
Server.Extensions.PerMessage_Deflate.Enabled = true
 
• Then every 5 seconds the server broadcast an image stream to all connected clients
 

procedure TfrmServerSnapshots.DoBroadcastStream;
var
  oBitmap: TBitmap;
  oStream: TMemoryStream;
begin
  oBitmap := TBitmap.Create;
  try
    DoGetSnapshot(oBitmap);
    if WSServer.Active then
    begin
      oStream := TMemoryStream.Create;
      Try
        oBitmap.SaveToStream(oStream);
        oStream.Seek(0, soFromBeginning);
        WSServer.Broadcast(oStream);
      Finally
        FreeAndNil(oStream);
      End;
    end;
  finally
    oBitmap.FreeImage;
    FreeAndNil(oBitmap);
  end;
end;

606
DEMOS

Demos | Client Snapshots


This demo shows how read binary websocket messages, using TsgcWebSocketClient, which connects to a Web­
Socket Server, and receives a stream which is an image that is shown to user.
 

Connect to Server
• First create a new instance of TsgcWebSocketClient.
• Then configure the server Host and Port.
• Enable compression to receive less bytes when message is transmitted from server.
 
Client.Extensions.PerMessage_Deflate.Enabled = true
 
• The image sent by server arrives as a stream, so use OnBinary event to read images.
 

procedure TfrmClientSnapshots.WSClientBinary(Connection: TsgcWSConnection; const Data: TMemoryStream);


var
  oBitmap: TBitmap;
begin
  oBitmap := TBitmap.Create;
  Try
    oBitmap.LoadFromStream(Data);
    Image1.Picture.Assign(oBitmap);
    memoLog.Lines.Add(
      '#image uncompressed size: ' + IntToStr(Data.Size) +
      '. Total received: ' + IntToStr(Connection.RecBytes));
  Finally
    FreeAndNil(oBitmap);
  End;
end;

607
DEMOS

Demos | Upload File


This demo shows how upload a file from web browser to a server using websocket protocol.
 

Configuration
• First create a new TsgcWebSocketServer instance, check the Server Chat Demo.
• The file will arrive to server as a binary stream, so you must handle OnBinary event to read the file.
 

procedure TfrmServer.WSServerBinary(Connection: TsgcWSConnection; const Data: TMemoryStream);


var
  oFile: TFileStream;
begin
  if FFileName = '' then
    FFileName := FormatDateTime('yyyymmddhhnnsszz', Now) + '.dat';
  oFile := TFileStream.Create(FFileName, fmCreate);
  Try
    oFile.CopyFrom(Data, Data.Size);
  Finally
    oFile.Free;
  End;
  memoLog.Lines.Add('Received File: ' + FFileName);
end;

• If you want to know the name of the file, you can send a text message before the file is sent with the name of
the file
 

procedure TfrmServer.WSServerMessage(Connection: TsgcWSConnection; const Text: string);


begin
  if LeftStr(Text, Length(CS_UPLOAD_FILE)) = CS_UPLOAD_FILE then
    FFileName := MidStr(Text, Length(CS_UPLOAD_FILE) + 1, Length(Text))
  else
    memoLog.Lines.Add('Message Received (' + Connection.Guid + '): ' + Text);
end;

The javascript code to send a file using websockets is shown below:

<script type='text/javascript'>
var ws;
function DoOpen()
{
  if ("WebSocket" in window)
  {
          ws = new sgcWebSocket("ws://127.0.0.1:5418");
          ws.on('open', function(evt){
ws.binaryType = "arraybuffer";                  
document.getElementById('status').innerHTML = "Socket Open";
document.getElementById('status').className = "online";
}
          );
          ws.on('close', function(evt){
document.getElementById('status').innerHTML = "Socket Closed";
document.getElementById('status').className = "offline";
                }                  
          );
          ws.on('error', function(evt){
document.getElementById('status').innerHTML = "Socket Error";
document.getElementById('status').className = "fail";
                }                  
          );
  }
}
function DoClose()
{
ws.close();
}
function DoUploadFile() {
var file = document.getElementById('filename').files[0];

608
DEMOS

var reader = new FileReader();


var rawData = new ArrayBuffer();            

reader.loadend = function() {

}
reader.onload = function(e) {
ws.send("uploadfile:" + file.name);
rawData = e.target.result;
ws.send(rawData);
document.getElementById('status').innerHTML = "File Uploaded";
document.getElementById('status').className = "online";
}
reader.readAsArrayBuffer(file);
}
</script>

609
DEMOS

Demos | Server Authentication


This demo show how use Server Authentication, if you want to know more about the different types of authentica­
tion, read the following article about Authentication.
 

Authentication
 
• First create a new instance of TsgcWebSocketServer. Enable Authentication property,
server.Authentication.Enabled = true;
• Then, check in OnAuthentication event handler if the username and password are correct. If they are cor­
rect, set the Authenticated property to true, otherwise set to false.
 

procedure TfrmServer.WSServerAuthentication(Connection: TsgcWSConnection;


    aUser, aPassword: string; var Authenticated: Boolean);
begin
  if (aUser = 'user') and (aPassword = '1234') then
    Authenticated := True;
end;

610
DEMOS

Demos | KendoUI_Grid
This demo show how KendoUI Grid works using WebSockets as protocol and a Web Browser as a client. Basically
is a javascript grid that is updated when any of the clients makes any change, these changes are updated using
websocket protocol to all connected clients, so all clients can see in real-time the same data, including all changes
made by clients.
 

Configuration
• First create a new TsgcWebSocketHTTPServer instance, check the Server Chat Demo.
• Then you must handle OnCommandGet to send the required files requested by web browser clients.
 

procedure TfrmServerPROTOCOL.WSServerCommandGet(AContext: TIdContext; ARequestInfo:


    TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  if ARequestInfo.Document = '/jquery.mobile.css' then
  begin
    AResponseInfo.ContentText := pageJQueryMobileCSS.Content;
    AResponseInfo.ContentType := 'text/css';
    AResponseInfo.ResponseNo := 200;
  end
  else if ARequestInfo.Document = '/jquery.js' then
  begin
    AResponseInfo.ContentText := pageJQuery.Content;
    AResponseInfo.ContentType := 'text/javascript';
    AResponseInfo.ResponseNo := 200;
  end
  else if ARequestInfo.Document = '/jquery.mobile.js' then
  begin
    AResponseInfo.ContentText := pageJQueryMobile.Content;
    AResponseInfo.ContentType := 'text/javascript';
    AResponseInfo.ResponseNo := 200;
  end
  else
  begin
    if AContext.Connection.Socket.Binding.Port = WSServer.SSLOptions.Port then
      FRequestSSL := True
    else
      FRequestSSL := False;
    AResponseInfo.ContentText := pageKendoUI_Grid.Content;
    AResponseInfo.ContentType := 'text/html';
    AResponseInfo.ResponseNo := 200;
  end;
end;

WebSockets Updates
When a client updates a grid record, this change is transmitted to all connected clients using websocket protocol.
Use OnMessage event to get notified about grid changes. The messages are in JSON format so you only must
read the JSON text, decode it and send a response to the other peer.
 

procedure TfrmServerPROTOCOL.WSServerMessage(Connection: TsgcWSConnection; const Text: string);


var
  i: Integer;
  oJSON: TsgcJSON;
  oArray: IsgcObjectJSON;
  vText: string;
begin
  memoLog.Lines.Add(Connection.IP + ':' + Text);
  oJSON := TsgcJSON.Create(nil);
  Try
    oJSON.Read(Text);
    // ... read
    if oJSON.Node['type'].Value = 'read' then
    begin
      oArray := oJSON.AddArray('data');
      for i := 1 to 20 do

611
DEMOS

      begin
        With oArray.JSONObject.AddObject(IntToStr(i)).JSONObject do
        begin
          AddPair('ContactID', i);
          AddPair('ContactName', ContactName[i]);
          AddPair('ContactTitle', ContactTitle[i]);
          AddPair('CompanyName', CompanyName[i]);
          AddPair('Country', Country[i]);
        end;
      end;
      Connection.WriteData(oJSON.Text);
    end
    // ... update
    else if oJSON.Node['type'].Value = 'update' then
    begin
      WSServer.Broadcast(StringReplace(Text, '"type":"update"', '"type":"push-update"', []), '', '',
        Connection.Guid);
      Connection.WriteData(Text);
    end
    // ... destroy
    else if oJSON.Node['type'].Value = 'destroy' then
    begin
      WSServer.Broadcast(StringReplace(Text, '"type":"destroy"', '"type":"push-destroy"', []), '', '',
        Connection.Guid);
      Connection.WriteData(Text);
    end
    // ... create
    else if oJSON.Node['type'].Value = 'create' then
    begin
      vText := StringReplace(Text, 'null', formatDateTime('yyyymmddhhnnsszzz', Now), []);
      WSServer.Broadcast(StringReplace(vText, '"type":"create"', '"type":"push-create"', []), '', '',
        Connection.Guid);
      Connection.WriteData(vText);
    end;
  Finally
    FreeAndNil(oJSON);
  End;
end;

612
DEMOS

Demos | ServerSentEvents
This demo show how Server Sent Events works in WebSocket Server. sgcWebSockets allows that the server can
handle more than one protocol on the same listening port.
 
You can read more about Server Sent Events.
 
This demo shows how the Server will send every second the time to all connected clients using Server Sent
Events.
 
Once the server is started, broadcasts to all connected clients a message with the Server Time, so every time the
client receives this message, it shows to user.
 

procedure TfrmServer.Timer1Timer(Sender: TObject);


begin
  WSServer.Broadcast('data: ' + 'Server Time: ' + FormatDateTime('hh:nn:ss', Now));
end;

The javascript code to handle the websocket connection is shown below:


 

socket = new sgcWebSocket('sse', '', 'sse');


socket.on('open', function(evt){                  
  document.getElementById('status').innerHTML = "Socket Open";
  document.getElementById('status').className = "online";
  }
);
socket.on('close', function(evt){
  document.getElementById('status').innerHTML = "Socket Closed";
  document.getElementById('status').className = "offline";
  }                  
);
socket.on('message', function(evt){
  document.getElementById('log').innerHTML = evt.message;
  }
);
socket.on('error', function(evt){
  document.getElementById('status').innerHTML = "Socket Error";
  document.getElementById('status').className = "fail";
  }                  
);

613
DEMOS

Demos | Server WebRTC


This demo shows how build a Video Conference Server using TsgcWebSocketHTTPServer and WebRTC as
javascript library.
 
The demo uses WebSocket protocol to signal WebRTC and uses public STUN/TURN servers, for production sites,
you need to use your own STUN/TURN servers. Registered users can download Coturn for windows, which is al­
ready compiled and with all the required libraries to run in your servers.
 
The client must be a web browser with support for WebRTC connections.
 

Configuration
• First create a new TsgcWebSocketHTTPServer instance, check the Server Chat Demo.
• Then, create a new instance of TsgcWSPServer_WebRTC.  
• After that, you must assign the WebRTC Protocol to WebSocket Server and configure the server host and
port.
 

WSServer.Port := StrToInt(txtDefaultPort.Text);
// ... bindings
With WSServer.Bindings.Add do
begin
  Port := StrToInt(txtDefaultPort.Text);
  IP := txtHost.Text;
end;
// ... active
WSServer.Active := True;

The demo requires an index HTML page which is used to dispatch the WebRTC front page, this page is provided
with the demo.
 

Run in WebBrowser
Once configured the server, start it and select one of the web-browsers available. It will open a new Web-Browser
session asking to start a new session. If successful you will see your video and if you open the same url in another
web-browser, you will see both peers connected.
 
The demo runs by default without SSL, this is only valid for localhost connections. For production sites, use SSL
connections. Check Server Chat Demo to configure SSL in server side.

614
DEMOS

Demos | Server AppRTC


This demo shows how build a Video Conference Server using TsgcWebSocketHTTPServer and AppRTC as
javascript library.
 
The demo uses WebSocket protocol to signal WebRTC and uses public STUN/TURN servers, for production sites,
you need to use your own STUN/TURN servers. Registered users can download Coturn for windows, which is al­
ready compiled and with all the required libraries to run in your servers.
 
The client must be a web browser with support for WebRTC connections.
 

Configuration
• First create a new TsgcWebSocketHTTPServer instance, check the Server Chat Demo.
• Then, create a new instance of TsgcWSPServer_AppRTC.
• After that, you must assign the AppRTC Protocol to WebSocket Server and configure the server host and
port. WebRTC requires secure connections, so you will need to use a PEM certificate and configure the SS­
LOptions property of the component.
 

WSServer.Port := StrToInt(txtDefaultPort.Text);
// ... bindings
With WSServer.Bindings.Add do
begin
  Port := StrToInt(txtDefaultPort.Text);
  IP := txtHost.Text;
end;
// ... properties
WSPAppRTC.AppRTC.RoomLink := 'https://' + txtHost.Text + ':' + txtDefaultPort.Text + '/r/';
WSPAppRTC.AppRTC.WebSocketURL := 'wss://' + txtHost.Text + ':' + txtDefaultPort.Text;
// ... active
WSServer.Active := True;

• AppRTC.RommLink is the url where the web-browser will be redirected to login to a room
• AppRTC.WebSocketURL is the url of the websocket connection
• The IceServers can be configured in the AppRTC Server protocol.
 
The demo requires an index HTML page which is used to dispatch the AppRTC front page, this page is provided
with the demo.
 

Run in WebBrowser
Once configured the server, start it and select one of the web-browsers available. It will open a new Web-Browser
session asking to join a new room. Join this room and if successful you will see a link which must be used from an­
other web-browser to start a new video-conference.
 

615
DEMOS

616
DEMOS

Demos | Telegram Client


This demo shows how connect to Telegram, receive all contacts, send Text messages, send Images... and much
more
 

Configuration
• First create a new instance of TsgcTDLib_Telegram.
• Then, before you try to connect to telegram, you must pass some parameters to client component like API
Hash, API Id... Once you must set all required parameters, set property Active = true to start a connection.
 

sgcTelegram.Telegram.API.ApiHash := txtApiHash.Text;
sgcTelegram.Telegram.API.ApiId := txtApiId.Text;
sgcTelegram.Telegram.PhoneNumber := '';
sgcTelegram.Telegram.BotToken := '';
if chkLoginBot.Checked then
  sgcTelegram.Telegram.BotToken := txtBotToken.Text
else
  sgcTelegram.Telegram.PhoneNumber := txtPhoneNumber.Text;

sgcTelegram.Active := True;

• When client tries to connect to Telegram, usually a code is required, so you must handle OnTelegramAu­
thenticationCode and return the Code parameter with the value provided by your Telegram account.
 

procedure TFRMSGCTelegram.sgcTelegramAuthenticationCode(Sender: TObject;


  var Code: string);
begin
  Code := InputBox('Telegram', 'Introduce Telegram Code', '');
end;

Send Telegram Messages


To send a telegram message (text, files, images...) always requires first set the ChaId where you want to send the
message and then the parameter that can be a text message, a filename...
 

// send text message


sgcTelegram.SendTextMessage('456413', 'Hello From sgcWebSockets!!!');

// send file message


sgcTelegram.SendDocumentMessage('383784', 'c:\yourfile.txt');

Receive Telegram Messages


Messages received by Telegram client, are handled on specific event Handlers. There is an event when a next Text
Message is received, when a new Document is received, photo...
 

procedure TFRMSGCTelegram.sgcTelegramMessageText(Sender: TObject;


  MessageText: TsgcTelegramMessageText);
begin
  DoLogMessage(MessageText.ChatId, IntToStr(MessageText.SenderUserId),
    MessageText.Text);
end;

617
DEMOS

procedure TFRMSGCTelegram.sgcTelegramMessageDocument(Sender: TObject;


    MessageDocument: TsgcTelegramMessageDocument);
begin
  DoLogMessage(MessageDocument.ChatId, IntToStr(MessageDocument.SenderUserId),
    'New Document: ' + MessageDocument.FileName);
end;

618
THIRD-PARTIES

Coturn
Coturn
 
From sgcWebSockets 4.5.2 ENTERPRISE Edition, you can build your own STUN/TURN server using Delphi/
CBuilder.
 
It's a free open source implementation of TURN and STUN Servers.
The TURN Server is a VoIP media traffic NAT traversal server and gateway. It can be used as a general-purpose
network traffic TURN server and gateway, too.
 
The supported project target platforms are:
• Linux
• Mac OS X
• Windows (Cygwin): compiled binaries are available for registered users.
 

Windows Configuration
First you must download compiled binaries from your account, there are 2 available versions: win32 and win64. Se­
lect the desired platform and uncompress binaries in a folder. The following files will be created:
 
1. Some cygwin libraries required to run application, you must deploy these libraries with coturn server.
2. Some console applications:
2.1 turnserver.exe: is the main console application to run a TURN/STUN server
2.2 Other applications: are used to configure or testing purposes.
3. Turnserver.conf: is the configuration file for coturn server.
 

turnserver.conf

This is the configuration file for coturn server, if you open you will se a default configuration.
 

619
THIRD-PARTIES

Simple Configuration
 
Your server has the following public IP 80.15.44.123 and listens on port 80. The credentials for connecting are:
username = demo, password = secret
Set the following configuration:
 
listening-ip=80.15.44.123
listening-port=80
realm=yourrealm.com
user=demo:secret
 
 
 
Configuration with TLS enabled
 
Server has the following public IP 80.15.44.123 and listens on port 80 and 443 (TLS connections). The credentials
for connecting are: username = demo, password = secret. Your certificate name (must be in PEM format) is
certificate.crt and private key is private.key.
Set the following configuration:
 
listening-ip=80.15.44.123
listening-port=80
realm=yourrealm.com
tls-listening-port=443
cert=certificate.crt
pkey=private.key
user=demo:secret
 
There are more configurations available, just open turnserver.conf and read the documented sections.
 
Run coturn
 
Once configured, you can run server just executing turnserver.exe, a new console application will be opened and a
log file will be created. You can increase the verbose of console application (get more detailed messages) if you en­
able "verbose" in turnserver.conf file.
 

 
 

620
REFERENCE

WebSockets
WebSocket is a web technology providing for bi-directional, full-duplex communications channels, over a single
Transmission Control Protocol (TCP) socket.
 
The WebSocket API is being standardized by the W3C, and the WebSocket protocol has been standardized by the
IETF as RFC 6455.
WebSocket is designed to be implemented in web browsers and web servers, but it can be used by any client or
server application. The WebSocket protocol makes possible more interaction between a browser and a web site,
facilitating live content and the creation of real-time games. This is made possible by providing a standardized way
for the server to send content to the browser without being solicited by the client, and allowing for messages to be
passed back and forth while keeping the connection open. In this way a two-way (bi-direction) ongoing conversa­
tion can take place between a browser and the server. A similar effect has been done in non-standardized ways us­
ing stop-gap technologies such as comet.
 
In addition, the communications are done over the regular TCP port number 80, which is of benefit for those envi­
ronments which block non-standard Internet connections using a firewall. WebSocket protocol is currently support­
ed in several browsers including Firefox, Google Chrome, Internet Explorer and Safari. WebSocket also requires
web applications on the server to be able to support it.
 
More Information
Browser Support

621
REFERENCE

HTTP/2
HTTP/2 will make our applications faster, simpler, and more robust — a rare combination — by allowing us to undo
many of the HTTP/1.1 workarounds previously done within our applications and address these concerns within
the transport layer itself. Even better, it also opens up a number of entirely new opportunities to optimize our ap­
plications and improve performance!

The primary goals for HTTP/2 are to reduce latency by enabling full request and response multiplexing, minimize
protocol overhead via efficient compression of HTTP header fields, and add support for request prioritization and
server push. To implement these requirements, there is a large supporting cast of other protocol enhancements,
such as new flow control, error handling, and upgrade mechanisms, but these are the most important features
that every web developer should understand and leverage in their applications.

HTTP/2 does not modify the application semantics of HTTP in any way. All the core concepts, such as HTTP
methods, status codes, URIs, and header fields, remain in place. Instead, HTTP/2 modifies how the data is format­
ted (framed) and transported between the client and server, both of which manage the entire process, and hides
all the complexity from our applications within the new framing layer. As a result, all existing applications can be
delivered without modification.

More information

622
REFERENCE

JSON
JSON or JavaScript Object Notation, is a text-based open standard designed for human-readable data inter­
change. It is derived from the JavaScript scripting language for representing simple data structures and associative
arrays, called objects. Despite its relationship to JavaScript, it is language-independent, with parsers available for
many languages.
 
The JSON format is often used for serializing and transmitting structured data over a network connection. It is used
primarily to transmit data between a server and web application, serving as an alternative to XML.
 
More Information

623
REFERENCE

JSON-RPC 2.0
JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. Primarily this specification defines
several data structures and the rules around their processing. It is transport agnostic in that the concepts can be
used within the same process, over sockets, over http, or in many various message passing environments. It uses
JSON (RFC 4627) as data format.
 
Example: client call method subtract with 2 params (42 and 23). Server sends a result of 19.
 
Client To Server --> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
 
Server To Client<-- {"jsonrpc": "2.0", "result": 19, "id": 1}
 
 

Parsers
sgcWebSockets provides a built-in JSON component, but you can use your own JSON parser. Just implement fol­
lowing interfaces located at sgcJSON.pas:
 
IsgcJSON
IsgcObjectJSON
 
There are 3 implementations of theses interfaces
 
• sgcJSON.pas: default JSON parser provided.
• sgcJSON_System.pas: uses JSON parser provided with latest versions of delphi.
• sgcJSON_XSuperObject.pas: uses JSON library written by Onur YILDIZ, you can download sources
from: https://github.com/onryldz/x-superobject
 
To use your own JSON parser or use some of the JSON parsers provided, just call SetJSONClass in your initial­
ization method. For example: if you want use XSuperObject JSON parser, just call:
 
  SetJSONClass(TsgcXSOJSON)
 
If you don't call this method, sgcJSON will be used by default.
 
 
More information

624
REFERENCE

WAMP
The WebSocket Application Messaging Protocol (WAMP) is an open WebSocket subprotocol that provides two
asynchronous messaging patterns: RPC and PubSub.
 
The WebSocket Protocol is already built into modern browsers and provides bidirectional, low-latency message-
based communication. However, as such, WebSocket it is quite low-level and only provides raw messaging.
 
Modern Web applications often have a need for higher level messaging patterns such as Publish & Subscribe and
Remote Procedure Calls.
 
This is where The WebSocket Application Messaging Protocol (WAMP) enters. WAMP adds the higher level mes­
saging patterns of RPC and PubSub to WebSocket - within one protocol.
 
Technically, WAMP is an officially registered WebSocket subprotocol (runs on top of WebSocket) that uses JSON
as message serialization format.
 
More Information

625
REFERENCE

WebRTC
WebRTC is a free, open project that enables web browsers with Real-Time Communications (RTC) capabilities via
simple Javascript APIs. The WebRTC components have been optimized to best serve this purpose. The WebRTC
initiative is a project supported by Google, Mozilla and Opera.
 
WebRTC offers web application developers the ability to write rich, real-time multimedia applications (think video
chat) on the web, without requiring plugins, downloads or installs. Its purpose is to help build a strong RTC platform
that works across multiple web browsers, across multiple platforms.
 
More Information

626
REFERENCE

MQTT
MQTT (MQ Telemetry Transport or Message Queue Telemetry Transport) is an ISO standard (ISO/IEC PRF 20922)
publish-subscribe-based "lightweight" messaging protocol for use on top of the TCP/IP protocol. It is designed for
connections with remote locations where a "small code footprint" is required or the network bandwidth is limited.
The publish-subscribe messaging pattern requires a message broker. The broker is responsible for distributing
messages to interested clients based on the topic of a message. Andy Stanford-Clark and Arlen Nipper of Cirrus
Link Solutions authored the first version of the protocol in 1999.
 
The specification does not specify the meaning of "small code footprint" or the meaning of "limited network band­
width". Thus, the protocol's availability for use depends on the context. In 2013, IBM submitted MQTT v3.1 to the
OASIS specification body with a charter that ensured only minor changes to the specification could be
accepted.MQTT-SN is a variation of the main protocol aimed at embedded devices on non-TCP/IP networks, such
as ZigBee.
Historically, the "MQ" in "MQTT" came from IBM's MQ Series message queuing product line. However, queuing it­
self is not required to be supported as a standard feature in all situations.
 
Specification
More Info

627
REFERENCE

Server-Sent Events
Server-sent events (SSE) is a technology for where a browser gets automatic updates from a server via HTTP con­
nection. The Server-Sent Events EventSource API is standardized as part of HTML5 by the W3C.
 
A server-sent event is when a web page automatically gets updates from a server. This was also possible before,
but the web page would have to ask if any updates were available. With server-sent events, the updates come au­
tomatically.
 
Examples: Facebook/Twitter updates, stock price updates, news feeds, sport results, etc.
 
 
More information
Browser Support

628
REFERENCE

OAuth2
OAuth 2 is an authorization framework that enables applications to obtain limited access to user accounts on an
HTTP service, such as Facebook, and GitHub. It works by delegating user authentication to the service that hosts
the user account, and authorizing third-party applications to access the user account. OAuth 2 provides authoriza­
tion flows for web and desktop applications, and mobile devices.
 
Read more
Specification

629
REFERENCE

JWT
JSON Web Token is an Internet proposed standard for creating data with optional signature and/or optional encryp­
tion whose payload holds JSON that asserts some number of claims. The tokens are signed either using a private
secret or a public/private key. For example, a server could generate a token that has the claim "logged in as admin"
and provide that to a client. The client could then use that token to prove that it is logged in as admin.
 
The tokens can be signed by one party's private key (usually the server's) so that party can subsequently verify the
token is legitimate. If the other party, by some suitable and trustworthy means, is in possession of the correspond­
ing public key, they too are able to verify the token's legitimacy. The tokens are designed to be compact, URL-safe,
and usable especially in a web-browser single-sign-on (SSO) context. JWT claims can typically be used to pass
identity of authenticated users between an identity provider and a service provider, or any other type of claims as
required by business processes.
 
Read more
Specification

630
REFERENCE

STUN
Session Traversal Utilities for NAT (STUN) is a standardized set of methods, including a network protocol, for tra­
versal of network address translator (NAT) gateways in applications of real-time voice, video, messaging, and other
interactive communications.
 
STUN is a tool used by other protocols, such as Interactive Connectivity Establishment (ICE), the Session Initiation
Protocol (SIP), and WebRTC. It provides a tool for hosts to discover the presence of a network address translator,
and to discover the mapped, usually public, Internet Protocol (IP) address and port number that the NAT has allo­
cated for the application's User Datagram Protocol (UDP) flows to remote hosts. The protocol requires assistance
from a third-party network server (STUN server) located on the opposing (public) side of the NAT, usually the public
Internet.
 
Read more
Specification

631
REFERENCE

AMQP
The Advanced Message Queuing Protocol (AMQP) is an open standard application layer protocol for message-ori­
ented middleware. The defining features of AMQP are message orientation, queuing, routing (including point-to-
point and publish-and-subscribe), reliability and security.
 
AMQP mandates the behavior of the messaging provider and client to the extent that implementations from differ­
ent vendors are interoperable, in the same way as SMTP, HTTP, FTP, etc. have created interoperable systems.
Previous standardizations of middleware have happened at the API level (e.g. JMS) and were focused on stan­
dardizing programmer interaction with different middleware implementations, rather than on providing interoperabili­
ty between multiple implementations. Unlike JMS, which defines an API and a set of behaviors that a messaging
implementation must provide, AMQP is a wire-level protocol. A wire-level protocol is a description of the format of
the data that is sent across the network as a stream of bytes. Consequently, any tool that can create and interpret
messages that conform to this data format can interoperate with any other compliant tool irrespective of implemen­
tation language.
 
AMQP is a binary, application layer protocol, designed to efficiently support a wide variety of messaging applica­
tions and communication patterns. It provides flow controlled, message-oriented communication with message-de­
livery guarantees such as at-most-once (where each message is delivered once or never), at-least-once (where
each message is certain to be delivered, but may do so multiple times) and exactly-once (where the message will
always certainly arrive and do so only once), and authentication and/or encryption based on SASL and/or TLS. It
assumes an underlying reliable transport layer protocol such as Transmission Control Protocol (TCP).
 
The AMQP specification is defined in several layers: (i) a type system, (ii) a symmetric, asynchronous protocol for
the transfer of messages from one process to another, (iii) a standard, extensible message format and (iv) a set of
standardised but extensible 'messaging capabilities.'
 
Specification
More Info

632
REFERENCE

TURN
Traversal Using Relays around NAT (TURN) is a protocol that assists in traversal of network address translators
(NAT) or firewalls for multimedia applications. It may be used with the Transmission Control Protocol (TCP) and
User Datagram Protocol (UDP). It is most useful for clients on networks masqueraded by symmetric NAT devices.
TURN does not aid in running servers on well known ports in the private network through a NAT; it supports the
connection of a user behind a NAT to only a single peer, as in telephony, for example.
 
Read more
Specification

633
LICENSE

License
eSeGeCe Components End-User License Agreement
eSeGeCe Components ("eSeGeCe") End-User License Agreement ("EULA") is a legal agreement between you (ei­
ther an individual or a single entity) and the Author of eSeGeCe for all the eSeGeCe components which may in­
clude associated software components, media, printed materials, and "online" or electronic documentation ("eS­
eGeCe components"). By installing, copying, or otherwise using the eSeGeCe components, you agree to be bound
by the terms of this EULA. This license agreement represents the entire agreement concerning the program be­
tween you and the Author of eSeGeCe, (referred to as "LICENSER"), and it supersedes any prior proposal, repre­
sentation, or understanding between the parties. If you do not agree to the terms of this EULA, do not install or use
the eSeGeCe components.
The eSeGeCe components are protected by copyright laws and international copyright treaties, as well as other in­
tellectual property laws and treaties. The eSeGeCe components are licensed, not sold.
If you want SOURCE CODE you need to pay the registration fee. You must NOT give the license keys and/or the
full editions of eSeGeCe (including the DCU editions and Source editions) to any third individuals and/or entities.
And you also must NOT use the license keys and/or the full editions of eSeGeCe from any third individuals' and/or
entities'.
1. GRANT OF LICENSE
The eSeGeCe components are licensed as follows:
(a) Installation and Use.
LICENSER grants you the right to install and use copies of the eSeGeCe components on your computer running a
validly licensed copy of the operating system for which the eSeGeCe components were designed [e.g., Windows
2000, Windows 2003, Windows XP, Windows ME, Windows Vista, Windows 7, Windows 8, Windows 10].
(b) Royalty Free.
You may create commercial applications based on the eSeGeCe components and distribute them with your exe­
cutables, no royalties required.
(c) Modifications (Source editions only).
You may make modifications, enhancements, derivative works and/or extensions to the licensed SOURCE CODE
provided to you under the terms set forth in this license agreement.
(d) Backup Copies.
You may also make copies of the eSeGeCe components as may be necessary for backup and archival purposes.
2. DESCRIPTION OF OTHER RIGHTS AND LIMITATIONS
(a) Maintenance of Copyright Notices.
You must not remove or alter any copyright notices on any and all copies of the eSeGeCe components.
(b) Distribution.
You may not distribute registered copies of the eSeGeCe components to third parties. Evaluation editions available
for download from the eSeGeCe official websites may be freely distributed.
You may create components/ActiveX controls/libraries which include the eSeGeCe components for your applica­
tions but you must NOT distribute or publish them to third parties.
(c) Prohibition on Distribution of SOURCE CODE (Source editions only).
You must NOT distribute or publish the SOURCE CODE, or any modification, enhancement, derivative works and/
or extensions, in SOURCE CODE form to third parties.
You must NOT make any part of the SOURCE CODE be distributed, published, disclosed or otherwise made avail­
able to third parties.
(d) Prohibition on Reverse Engineering, Decompilation, and Disassembly.
You may not reverse engineer, decompile, or disassemble the eSeGeCe components, except and only to the extent
that such activity is expressly permitted by applicable law notwithstanding this limitation.
(e) Rental.
You may not rent, lease, or lend the eSeGeCe components.
(f) Support Services.
LICENSER may provide you with support services related to the eSeGeCe components ("Support Services"). Any
supplemental software code provided to you as part of the Support Services shall be considered part of the eS­
eGeCe components and subject to the terms and conditions of this EULA.
eSeGeCe is licensed to be used by only one developer at a time. And the technical support will be provided to only
one certain developer.
(g) Compliance with Applicable Laws.
You must comply with all applicable laws regarding use of the eSeGeCe components.
3. TERMINATION
Without prejudice to any other rights, LICENSER may terminate this EULA if you fail to comply with the terms and
conditions of this EULA. In such event, you must destroy all copies of the eSeGeCe components in your posses­
sion.

634
LICENSE

4. COPYRIGHT
All title, including but not limited to copyrights, in and to the eSeGeCe components and any copies thereof are
owned by LICENSER or its suppliers. All title and intellectual property rights in and to the content which may be ac­
cessed through use of the eSeGeCe components are the property of the respective content owner and may be pro­
tected by applicable copyright or other intellectual property laws and treaties. This EULA grants you no rights to use
such content. All rights not expressly granted are reserved by LICENSER.
5. NO WARRANTIES
LICENSER expressly disclaims any warranty for the eSeGeCe components. The eSeGeCe components are pro­
vided "As Is" without any express or implied warranty of any kind, including but not limited to any warranties of mer­
chantability, non-infringement, or fitness of a particular purpose. LICENSER does not warrant or assume responsi­
bility for the accuracy or completeness of any information, text, graphics, links or other items contained within the
eSeGeCe components. LICENSER makes no warranties respecting any harm that may be caused by the transmis­
sion of a computer virus, worm, time bomb, logic bomb, or other such computer program. LICENSER further ex­
pressly disclaims any warranty or representation to Authorized Users or to any third party.
6. LIMITATION OF LIABILITY
In no event shall LICENSER be liable for any damages (including, without limitation, lost profits, business interrup­
tion, or lost information) rising out of "Authorized Users" use of or inability to use the eSeGeCe components, even if
LICENSER has been advised of the possibility of such damages. In no event will LICENSER be liable for loss of
data or for indirect, special, incidental, consequential (including lost profit), or other damages based in contract, tort
or otherwise. LICENSER shall have no liability with respect to the content of the eSeGeCe components or any part
thereof, including but not limited to errors or omissions contained therein, libel, infringements of rights of publicity,
privacy, trademark rights, business interruption, personal injury, and loss of privacy, moral rights or the disclosure of
confidential information.

635
LICENSE

Index
Add Telegram Proxy 449 Certificate-Based Connection 500
ALPN 87 Token-Based Connection 499
Amazon SQS 531 APP 496
AMQP 632 Apple Push Notifications 495
AMQP Channels 217 Authentication 71, 128, 149
AMQP Consume Messages 225 Binance Connect 312
AMQP Exchanges 219 Binance Get Market Data 314
AMQP Get Messages 227 Binance Private Requests Time 318
AMQP Publish Messages 224 Binance Private REST API 315
AMQP Queues 221 Binance Subscribe 313
API 3Commas 430 Binance Trade Spot 316
API Binance 324 Binary Message 125
API Binance Futures 324 Bindings 80, 141
API Binance Futures Trade 324 Bot 447
API Bitfinex 411 Broadcast 79
API Bitmex 404 Build 44, 45, 47, 48
API Bittrex 401 Build Android Application 47
API Blockchain 433 Build iOS Application 48
API Cex 421 Build OSX Application 45
API Coinbase 327 Certificate-Based Connection 500
API Coinbase Pro 327 APNs 500
API Discord 415 Certificates OpenSSL 119
API FTX 382 Certificates SChannel 120
API Huobi 418 Channels 79, 217, 313, 333, 391, 586
API Kraken 346, 348, 354, 357, 359, 362, 363, Client 110, 112, 113, 123, 124, 125, 128, 130,
369, 375, 377 131, 132, 133, 154, 200, 202, 203, 215, 216,
API Kraken Futures 362, 363, 369, 375, 377 292, 486, 487, 489, 490, 571, 572, 573, 583,
API Kraken Futures REST Private 377 584, 585, 586, 598, 599, 600, 602, 607, 617
API Kraken Futures REST Public 375 Client AMQP Connect 215
API Kraken REST Private 359 Client AMQP Disconnect 216
API Kraken REST Public 357 Client Authentication 128, 490
API Pusher 395 Client Chat 598
API SignalR 344 Client Close Connection 112, 486
API SignalRCore 339 Client Exceptions 130
API SocketIO 325 Client Keep Connection Active 487
API Telegram 435 Client Keep Connection Open 113
APIs 305, 312, 315, 324, 325, 327, 332, 335, Client MQTT Connect 200
339, 344, 346, 348, 354, 357, 359, 362, 363, Client MQTT Sessions 202
369, 375, 377, 382, 390, 393, 395, 401, 404, Client MQTT Version 203
411, 415, 418, 421, 430, 433, 435 Client Open Connection 110
APNs 496, 498, 499, 500 Client Pending Requests 489

636
LICENSE

Client Proxies 133 FTX Private REST API 393


Client Register Protocol 132 FTX Subscribe 391
Client Send Binary Message 124 Generate 497
Client Send Text 123, 125 Remote Notification APNs 497
Client Send Text Message 123 Google Calendar 555, 561, 562, 563
Client Snapshots 607 Google Calendar RefreshToken 563
Client SocketIO 602 Google Calendar Sync Calendars 561
Client WebSocket HandShake 131 Google Calendar Sync Events 562
Clients 202, 215, 292, 487, 489, 598, 600 Google Cloud Pub 546
Send Files 292 Google OAuth2 Keys 536
Coinbase Pro Connect 332 Google Service Accounts 542
Coinbase Pro Get Market Data 334 HeartBeat 75
Coinbase Pro Place Orders 337 HTTP 40, 78, 88, 159, 160, 165, 166, 174, 474,
Coinbase Pro Private Requests Time 336 481
Coinbase Pro Private REST API 335 HTTP Dispatch Files 160
Coinbase Pro SandBox Account 338 HTTP/2 161, 162, 164, 482, 483, 484, 485,
Coinbase Pro Subscribe 333 488, 491, 622
Compression 83 HTTP/2 Alternate Service 164
Configure Install 33 HTTP/2 Download File 483
Connect Mosquitto 201 HTTP/2 Headers 485
Connect Secure Server 118 HTTP/2 Partial Responses 484
Connect TCP Server 115 HTTP/2 Reason Disconnection 488
Connect WebSocket Server 109 HTTP/2 Server Push 162, 482
Connections TIME_WAIT 116 HTTP1 502
Coturn 619 HTTP2 475
CryptoHopper 452 HTTPAPI 172, 174, 175, 178
Custom Objects 85 HTTPAPI Custom Headers 175
Custom Sub 68 HTTPAPI Disable HTTP 174
Datasnap 592 HTTPAPI OnDisconnect 178
Deflate-Frame 461 In HTML 518
Dropped Disconnections 114 Indy 63
Editions 18 Install Errors 30
Error 165 Install Package 23
Extensions 459 Installation 20
Fast Performance Server 50 IOCP 86
Files 81, 100, 160, 291, 292, 293, 483, 608 IoT 462, 470
Fired 178 IoT Azure MQTT Client 470
Flash 84 JSON 623
Flow 42 JWT 524, 630
Threading 42 KendoUI_Grid 611
Forward HTTP Requests 88 License 634
Found 447 LoadBalancing 99
Fragmented Messages 102 Logs 77
FTX Connect 390 Memory Manager 52
FTX Get market Data 392 Method 481
FTX Place Orders 394

637
LICENSE

MQTT 200, 201, 202, 203, 204, 205, 206, 207, Protocols Javascript 189
208, 209, 210, 470, 600, 627 Proxy 101, 133, 449
MQTT Clear Retained Messages 210 Quality 89
MQTT Publish 204, 207, 209 Service 89
MQTT Publish Message 207 Quality Of Service 89
MQTT Publish Subscribe 204 Queues 91, 221
MQTT Receive Messages 208 QuickStart HTTP 40
MQTT Subscribe 206 QuickStart WebSockets 38
MQTT Topics 205 RCON 451
Notification Requests 498 Receive Binary Messages 127, 153
Sending 498 Receive Text Messages 126, 152
OAuth2 491, 504, 514, 518, 519, 520, 521, Register 450, 496
522, 523, 536, 629 Register Telegram User 450
OAuth2 Customize Sign 518 Remote Notification APNs 497
OAuth2 None Authenticate URLs 523 Generate 497
OAuth2 Recover Access Tokens 521 Request HTTP 481
OAuth2 Register Apps 520 Response Body 165
OpenSSL 55, 57, 58, 60, 61, 119 RTCMultiConnection 457
OpenSSL Android 60 SChannel Get Connection Info 122
OpenSSL iOS 61 Secure Connections 73
OpenSSL OSX 58 Self-Signed Certificates 173
OpenSSL Windows 57 Send Big Files 293
Overview 36 Send Files 291, 292
PerMessage-Deflate 460 Clients 292
Post Big Files 81 Server 291
Protocol AMQP 211 Send Files To Clients 292
Protocol AppRTC 239 Send Files To Server 291
Protocol Dataset 274, 280, 283, 284 Send Telegram Message Bold 446
Protocol Dataset Javascript 280 Send Telegram Message With Buttons 444,
Protocol Dataset Notify Updates 284 445
Protocol Dataset Replicate Table 283 Send Telegram Message With Inline Buttons
Protocol Default 263, 270 444
Protocol Default Javascript 270 Sending 498
Protocol Files 285 Notification Requests 498
Protocol MQTT 192 Server 140, 141, 142, 143, 144, 146, 147, 148,
Protocol Presence 294, 302 149, 150, 151, 152, 153, 154, 159, 161, 166,
Protocol Presence Javascript 302 172, 201, 291, 482, 514, 519, 522, 576, 577,
Protocol STOMP 231 590, 591, 596, 603, 606, 610, 614, 615
Protocol WAMP 244, 249 Send Files 291
Protocol WAMP Javascript 249 Server AppRTC 615
Protocol WAMP2 257 Server Authentication 149, 522, 610
Protocol WebRTC 241, 243 Server Bindings 141
Protocol WebRTC Javascript 243 Server Chat 596
Protocols 68, 132, 187, 189, 192, 211, 231, Server Close Connection 148
239, 241, 243, 244, 249, 257, 263, 270, 274, Server Endpoints 519
280, 283, 284, 285, 294, 302 Server Example 514

638
LICENSE

Server Keep Active 143 TsgcSTUNClient 568


Server Keep Connections Alive 146 TsgcSTUNServer 574
Server Monitor 603 TsgcTURNClient 579
Server Plain TCP 147 TsgcTURNServer 587
Server Read Headers 154 TsgcUDPClient 564
Server Requests 159 TsgcUDPServer 566
Server Send Binary Message 151 TsgcWebSocketClient_WinHTTP 179
Server Send Text Message 150 TsgcWebSocketHTTPServer 155
Server Sessions 166 TsgcWebSocketHTTPServer_Sessions 166
Server Snapshots 606 TsgcWebSocketLoadBalancerServer 181
Server SSL 144, 172 TsgcWebSocketProxyServer 182
Server Start 140 TsgcWebSocketServer 134
Server Startup Shutdown 142 TsgcWSHTTP2WebBrokerBridgeServer 594
Server-Sent Events 97, 628 TsgcWSHTTPWebBrokerBridgeServer 593
ServerSentEvents 613 TsgcWSMessageFile 290
Service 89, 164, 542 TsgcWSPClient_AMQP 212
Quality 89 TsgcWSPClient_Dataset 277
STUN 567, 571, 572, 573, 576, 577, 631 TsgcWSPClient_Files 288
STUN Client Attributes 573 TsgcWSPClient_MQTT 194
STUN Client Long Term Credentials 572 TsgcWSPClient_Presence 299
STUN Client UDP Retransmissions 571 TsgcWSPClient_sgc 267
STUN Server Alternate Server 577 TsgcWSPClient_STOMP 232
STUN Server Long Term Credentials 576 TsgcWSPClient_STOMP_ActiveMQ 236
Sub 546 TsgcWSPClient_STOMP_RabbitMQ 234
SubProtocol 95 TsgcWSPClient_WAMP 247
TCP Connections 94 TsgcWSPClient_WAMP2 258
Telegram Chat 447 TsgcWSPresenceMessage 298
Telegram Client 617 TsgcWSPServer_AppRTC 240
Telegram Get SuperGroup Members 448 TsgcWSPServer_Dataset 275
Threading 42 TsgcWSPServer_Files 286
Flow 42 TsgcWSPServer_Presence 295
Throttle 96 TsgcWSPServer_sgc 265
Token-Based Connection 499 TsgcWSPServer_WAMP 245
APNs 499 TsgcWSPServer_WebRTC 242
Transactions 93 TsgcWSServer_HTTPAPI_WebBrokerBridge
TsgcHTTP_JWT_Client 526 595
TsgcHTTP_JWT_Server 529 TURN 578, 583, 584, 585, 586, 590, 591, 633
TsgcHTTP_OAuth2_Client 505 TURN Client Allocate IP Address 583
TsgcHTTP_OAuth2_Server 511 TURN Client Create Permissions 584
TsgcHTTP2Client 476 TURN Client Send Indication 585
TsgcHTTP2ConnectionClient 492 TURN Server Allocations 591
TsgcHTTP2RequestProperty 493 TURN Server Long Term Credentials 590
TsgcHTTP2ResponseProperty 494 Upload File 608
TsgcIWWebSocketClient 183 Using DLL 66
TsgcIWWSPClient_Dataset 279 Wait Response 209
TsgcIWWSPClient_sgc 269 WAMP 252, 253, 254, 255, 625

639
LICENSE

WAMP Publishers 253 WebSocket Parameters Connection 65


WAMP RPC Progress Results 255 WebSocket Redirections 117
WAMP Simple RPC 254 WebSockets 38, 64, 65, 109, 117, 131, 312,
WAMP Subscribers 252 313, 332, 333, 348, 354, 363, 369, 390, 391,
WatchDog 76 621
Web Browser Test 67 WebSockets Private 354, 369
WebRTC 614, 626 WebSockets Public 348, 363
WebSocket Events 64

640
Copyright © 2012-2022 eSeGeCe.com
info@esegece.com
www.esegece.com

You might also like