sgcWebSockets IoT
Two components, one for AWS IoT Core and one for Azure IoT Hub. Both speak MQTT underneath, but each wraps its cloud's own conventions, so you work in the vendor's vocabulary (device shadows, device twins) rather than in raw topics.
Unlike the MQTT component in sgcwebsockets-mq, these are self-contained.
They own their transport and are started with Active := True. There is no
Client property and nothing to bind.
When to use this skill
- Connect a Delphi device or gateway to AWS IoT Core
- Connect one to Azure IoT Hub
- Read and write an AWS device shadow, or an Azure device twin
- Send telemetry up, and receive cloud-to-device messages back
- Authenticate with SigV4, a custom authoriser, or an Azure SAS token
If you are talking to a plain MQTT broker rather than one of these two clouds,
use TsgcWSPClient_MQTT from sgcwebsockets-mq instead. It is the same
protocol without the cloud-specific topic conventions.
Install and uses clause
uses
sgcIoT;
Both components live there. The MQTT option classes they expose are shared with
the MQTT client, so some of their types are documented as TsgcWSMQTT....
Before you start, ask the developer
Use a structured question tool if your host has one, for example Claude Code's
AskUserQuestion. Otherwise ask in chat:
- Which cloud? They are different components with different vocabularies. AWS calls the device's stored state a shadow, Azure calls it a twin.
- How does the device authenticate? AWS offers SigV4 signing, X.509 client certificates and a custom authoriser. Azure normally uses a SAS token from a connection string. This decides most of the configuration.
- Is there a device provisioning step? Devices are usually registered before they can connect, and that is console or API work, not code.
- What is the thing or device name? Nearly every AWS shadow call takes a thing name, and getting it wrong fails silently at the broker rather than raising.
Components in this skill
| Component | Cloud | State model |
|---|---|---|
TsgcIoTAmazon_MQTT_Client |
AWS IoT Core | Device shadow |
TsgcIoTAzure_MQTT_Client |
Azure IoT Hub | Device twin |
Quickstart, AWS IoT
uses
sgcIoT;
FAWS := TsgcIoTAmazon_MQTT_Client.Create(Self);
// ... configure FAWS.Amazon, and one of SignatureV4 or CustomAuthentication ...
FAWS.Active := True;
// the shadow is request/response over reserved topics: subscribe to the
// replies before you ask, or the answer arrives with nobody listening
FAWS.Subscribe_ShadowGetAccepted('my-thing');
FAWS.Subscribe_ShadowRejected('my-thing');
FAWS.Publish_ShadowGet('my-thing', '');
The shadow methods come in matched pairs. Publish_ShadowGet asks,
Subscribe_ShadowGetAccepted and Subscribe_ShadowRejected receive the two
possible answers. The same shape repeats for update and delete.
Publish_Rule sends into an AWS IoT rule, and the Subscribe_Client...
methods let you watch the lifecycle events of other devices, which is how a
gateway notices its fleet connecting and disconnecting.
Quickstart, Azure IoT
Azure starts from the connection string you get from the portal:
FAzure := TsgcIoTAzure_MQTT_Client.Create(Self);
FAzure.ReadConnectionString(GetConnectionStringFromConfig);
FAzure.Active := True;
FAzure.Subscribe_CloudToDevice;
FAzure.Send_DeviceToCloud('{"temperature":21.5}', azuIoTQoS1);
ReadConnectionString parses the string and fills in the host, device id and
SAS credentials, so you rarely set those individually.
Device twins follow the same request and response shape as AWS shadows, keyed by a request id you supply:
FAzure.Subscribe_DeviceTwins;
FAzure.Get_DeviceTwinsProperties('req-1');
FAzure.Set_DeviceTwinsProperties('req-2', '{"reported":{"fw":"1.2.0"}}');
Several Azure calls come in a plain and a ...AndWait form.
SendAndWait_DeviceToCloud and GetAndWait_DeviceTwinsProperties block until
the acknowledgement arrives or the timeout elapses, which is convenient in a
console tool and wrong in a UI thread.
Things that catch people out
- These are not the MQTT component. There is no
Clientto assign, and settingActive := Trueis what connects them. - Subscribe to the reply topics before publishing a shadow or twin request. The answer is a separate message on a separate topic, and if you subscribe afterwards you miss it.
- The AWS thing name and the Azure device id must match what was registered in the cloud. A mismatch is not an error, the broker simply never answers.
- Azure QoS is its own enumeration,
TazuIoTQoS, not the MQTTTmqttQoS. - The
...AndWaitcalls block. Use the event-driven form in a GUI. - Both clouds require TLS and a correctly dated device clock. A device whose clock is badly wrong fails the handshake with a certificate error that looks like a credentials problem.
Routing
- Find a component:
reference/components-index.mdlists every component, itsunit, and its edition, grouped by Reg module. - Uses clause: add the component's
unit:value (shown on its API page) to yourusesclause. Nothing compiles without it. - API detail:
reference/api/<Component>.mdhas the Properties, Events and Methods, each in both Delphi and C++Builder form. - Option / enum / event types: property and event types link to
reference/types/<TypeName>.md, which documents the sub-properties of option classes, the values of enums, and the parameter list of event handlers. - Examples:
examples/index.mdis the full demo catalog;examples/<Component>.mdis a focused, real usage snippet for the most-used components. - Concepts:
concepts/overview.md(getting started + uses-clause rule) andconcepts/editions-and-features.md(which components your edition includes). - Bundled resources:
concepts/resources.mdlists the browser-side assets (JavaScript, HTML, CSS) the server components serve or embed, so a browser client works without an external CDN. - Version history:
reference/history.mdlists what changed in each sgcWebSockets release.
Editions
Components are gated by edition (Professional, Enterprise, All-Access) or by a feature define. Check the edition column in the components index, or concepts/editions-and-features.md, before relying on a component.
Only public and published members are documented. Method bodies, private fields and protected members are intentionally not included.