sgcMQ in five minutes

Seven native messaging clients ship in this package. MQTT is the shortest path to something running, so that is what this page does: connect to a broker, subscribe to a topic, publish a message and watch it come back. AMQP, Kafka and STOMP follow the same two-component shape.

MQTT 3.1.1 and 5.0, AMQP 0.9.1 and 1.0, Kafka, STOMP
No external library and no DLL
Standard edition and up

Two components, not one

This is the part that trips people up. The protocol component speaks MQTT; a separate client component owns the socket. You connect them with one assignment.

The protocol component

TsgcWSPClient_MQTT on the SGC MQ palette page. It carries Connect, Subscribe, Publish, UnSubscribe and thirteen MQTT events.

The transport component

TsgcWebSocketClient for MQTT over WebSockets, or TsgcTCPClient for plain MQTT over TCP. Set Host and Port on this one.

The one line that joins them

MQTT.Client := WSClient;. After that you open the connection by setting WSClient.Active := True, not by calling a method on the protocol.

Platforms

sgcWebSocket_Protocol_MQTT_Client.pas has no platform guard, only a conditional Windows import, and the component is registered with ComponentPlatforms(0). Every target compiles.

Requirements and editions

The edition column is the define that gates each protocol, with the line it sits on in Source/sgcVer.inc.

What Value
IDE Delphi 7 through RAD Studio 13, and C++Builder 2007 through 13.
Uses clause sgcWebSocket_Protocols for TsgcWSPClient_MQTT, sgcWebSocket for the client, sgcWebSocket_Classes for TsgcWSConnection, and sgcWebSocket_Types for TmqttQoS.
MQTT edition SGC_MQTT is defined on line 717, inside the {$IFDEF SGC_EDT_STD} block that runs from line 675 to line 724. So Standard and up. The blocks are cumulative, so Professional, Enterprise and All-Access include it too.
The other protocols All in the same Standard block: SGC_STOMP on line 716, SGC_AMQP on 718, SGC_AMQP1 on 719, SGC_KAFKA on 720 and SGC_WAMP on 715. None of them is an Enterprise feature.
Edition, standalone package The sgcMQ product defines SGC_PACK_MQ on line 855, and its own block on lines 959 to 966 turns on the same five protocol defines.
Platforms No unit-scope platform guard on the MQTT client unit. The only conditional in its uses clause is {$IFDEF MSWINDOWS}Windows, {$ENDIF}.

Want a broker to test against without installing one? The shipped MQTT demo points at a public test broker on www.esegece.com, port 15675 for MQTT over WebSockets.

Install and find the palette page

sgcMQ ships inside the sgcWebSockets installer and also as its own package. The install is the same either way.

1. Unzip

Unzip the download to a folder, called {$DIR} below.

2. Library path

Tools, Options, Library. Add {$DIR}\source and the lib folder for your IDE, for example {$DIR}\libD13\$(Platform).

3. Build the packages

Open the package group for your IDE version under {$DIR}\Packages\. Compile the runtime .dpk first, then install the design-time dcl one.

4. Check the palette

A page called SGC MQ appears, holding the protocol clients your edition enables. On a Standard build and up, TsgcWSPClient_MQTT is there.

5. Open the demo

Open {$DIR}\Demos\02.WebSocket_Protocols\08.MQTT_Client. It is where the code below comes from, and it is already pointed at a live test broker.

Connect, subscribe, publish

Wire the protocol to a client, open the connection, subscribe to a topic and publish to it. The message comes back on OnMQTTPublish.

uClientMQTT.pas
uses
  Classes, SysUtils,
  // sgc
  sgcWebSocket, sgcWebSocket_Classes, sgcWebSocket_Protocols,
  sgcWebSocket_Types, sgcWebSocket_Protocol_MQTT_Client,
  sgcWebSocket_Protocol_MQTT_Message;

procedure TfrmClientPROTOCOL.FormCreate(Sender: TObject);
begin
  WSClient := TsgcWebSocketClient.Create(Self);
  WSClient.Host := 'www.esegece.com';
  WSClient.Port := 15675;
  WSClient.TLS := False;

  // ... attach the client to the MQTT protocol
  MQTT.Client := WSClient;

  // ... and THIS is what opens the connection.
  // There is no Connect call on the protocol component.
  WSClient.Active := True;
end;

For plain MQTT over TCP rather than over WebSockets, create a TsgcTCPClient from sgcTCP_Client_WS instead and point MQTT.Client at that. Nothing else changes, which is the reason the two components are separate.

uClientMQTT.pas
procedure TfrmClientPROTOCOL.btnSubscribeClick(Sender: TObject);
begin
  MQTT.Subscribe('sgc/quickstart');
end;

procedure TfrmClientPROTOCOL.btnPublishClick(Sender: TObject);
begin
  // topic, payload, QoS, retain
  MQTT.Publish('sgc/quickstart', 'hello from Delphi',
    mtqsAtLeastOnce, False);
end;

procedure TfrmClientPROTOCOL.btnUnsubscribeClick(Sender: TObject);
begin
  MQTT.UnSubscribe('sgc/quickstart');
end;

Publish returns a Word, the packet identifier, and does not wait. PublishAndWait returns a Boolean and blocks until the broker confirms, with a timeout that defaults to ten seconds. TmqttQoS comes from sgcWebSocket_Types.

uClientMQTT.pas
procedure TfrmClientPROTOCOL.MQTTMQTTConnect(Connection: TsgcWSConnection;
  const Session: Boolean; const ReasonCode: Integer;
  const ReasonName: String;
  const ConnectProperties: TsgcWSMQTTCONNACKProperties);
begin
  memoLog.Lines.Add('#connected: ' + ReasonName);
end;

procedure TfrmClientPROTOCOL.MQTTMQTTSubscribe(Connection: TsgcWSConnection;
  aPacketIdentifier: Word; aCodes: TsgcWSSUBACKS;
  SubscribeProperties: TsgcWSMQTTSUBACKProperties);
begin
  memoLog.Lines.Add('#subscribed: ' + IntToStr(aPacketIdentifier));
end;

procedure TfrmClientPROTOCOL.MQTTMQTTPublish(Connection: TsgcWSConnection;
  aTopic, aText: string;
  PublishProperties: TsgcWSMQTTPUBLISHProperties);
begin
  memoLog.Lines.Add(aTopic + ': ' + aText);
end;

These are the three that matter first. Nine more exist for the acknowledgement flow, disconnection and MQTT 5.0 authentication. Let the IDE generate the handlers, because the parameter lists are long and the properties objects differ per event.

All three tabs come from the shipped demo Demos\02.WebSocket_Protocols\08.MQTT_Client\uClientMQTT.pas, with the form controls replaced by literals. The MQTT object is placed on the form in that project; creating it in code works identically.

Prove the round trip

Two events tell you the broker accepted you and the topic is live.

OnMQTTConnect

The broker accepted the session. ReasonCode and ReasonName tell you why when it did not, which is far more useful than a dropped socket.

OnMQTTSubscribe

The subscription was granted. aCodes, a TsgcWSSUBACKS, carries the broker's per-topic answer, so a refused subscription is visible rather than silent.

OnMQTTPublish

A message arrived. Publish to the topic you just subscribed to and it comes straight back, which proves the whole path in one click.

The acknowledgement events

At QoS 1 and 2 delivery is confirmed later, on OnMQTTPubAck, OnMQTTPubRec, OnMQTTPubRel and OnMQTTPubComp. If you need a blocking call instead, use PublishAndWait.

What usually goes wrong the first time

Six problems account for nearly every failed first connection.

Nothing happens when you call Subscribe

The connection is not open yet. The protocol component does not open the socket; the client does. Set WSClient.Active := True and wait for OnMQTTConnect before subscribing.

Access violation on the first call

MQTT.Client was never assigned. That one line is what binds the protocol to a transport, and without it the protocol has nowhere to write.

Wrong port for the wrong transport

MQTT over WebSockets and MQTT over plain TCP are different ports on most brokers. 1883 and 8883 are the usual TCP ports, while the WebSocket endpoint is somewhere else entirely. The shipped demo uses 15675 for WebSockets.

You are looking for OnMQTTMessage

There is no such event. Inbound broker messages arrive on OnMQTTPublish for text, and on OnMQTTPublishEx when you want the raw payload and the full message object.

QoS 1 and 2 look like they did nothing

They are acknowledged asynchronously. Publish returns the packet identifier immediately; the acknowledgement arrives later on OnMQTTPubAck, OnMQTTPubRec, OnMQTTPubRel or OnMQTTPubComp. Use PublishAndWait when you want a blocking call.

The broker refuses the connection

Most brokers want a client identifier and credentials. Set them on Authentication, and use OnMQTTBeforeConnect when you need to compute the client identifier at connect time.

Beyond the first topic

The same two-component shape carries every other protocol in the package.

MQTT 5.0 properties

Set MQTTVersion and the request and response property objects become available. User properties, subscription identifiers, topic aliases and reason codes are all exposed.

MQTT reference

AMQP, both versions

Two separate clients, 0.9.1 for RabbitMQ style exchanges and queues, and 1.0 for the newer wire protocol. Both attach to a client the same way MQTT does.

AMQP 0.9.1 reference and AMQP 1.0 reference

Kafka and STOMP

A native Kafka wire protocol client, and STOMP 1.0 through 1.2 with broker-specific variants for RabbitMQ and ActiveMQ.

STOMP for RabbitMQ and STOMP for ActiveMQ

Talk to a cloud broker

AWS IoT and Azure IoT both speak MQTT, and the library ships dedicated components that handle their signing and authentication for you.

AWS IoT reference and Azure IoT reference

Reference, demos and documentation

The reference pages document every property and event. Demo projects ship inside the download, under Demos\02.WebSocket_Protocols.

Reference, MQTT client Every method, property and event on TsgcWSPClient_MQTT.
Reference, AMQP 0.9.1 Exchanges, queues, bindings and consumers.
Reference, AMQP 1.0 Links, sessions and the 1.0 message model.
TsgcWSPClient_MQTT component page The MQTT client in full, with the other six protocol clients linked from it.
Protocols overview How sub-protocol components attach to a client or a server.
Online help The generated reference, always in step with the current release.

Related reading: publishing and waiting for the acknowledgement, AMQP exchanges and queues and the Kafka client. Every product has its own quick start, listed on the getting started page.

sgcMQ quick start questions

Because the protocol and the transport are separate concerns, and that is what lets the same MQTT client run over plain TCP or over WebSockets without changing your code. TsgcWSPClient_MQTT encodes and decodes MQTT packets. TsgcWebSocketClient or TsgcTCPClient owns the socket, the host, the port and the TLS settings. One assignment joins them: MQTT.Client := WSClient;.
Set Active := True on the client component, not on the protocol. The shipped demo does exactly that. There is a Connect method on the protocol as well, but the demo does not use it, and setting Active is the path every sample follows.
SGC_MQTT is defined on line 717 of sgcVer.inc, inside the SGC_EDT_STD block that runs from line 675 to line 724. That is the Standard edition, the lowest paid tier, and the blocks are cumulative so every higher edition has it too. STOMP on line 716, AMQP on 718, AMQP 1.0 on 719 and Kafka on 720 are all in the same block. None of the messaging protocols is an Enterprise feature.
OnMQTTPublish, whose signature is procedure(Connection: TsgcWSConnection; aTopic, aText: String; PublishProperties: TsgcWSMQTTPUBLISHProperties). There is no event called OnMQTTMessage. When you need the raw bytes or the whole message object rather than a string, handle OnMQTTPublishEx instead.
Publish returns a Word, the packet identifier. Delivery is confirmed asynchronously: at QoS 1 on OnMQTTPubAck, at QoS 2 through OnMQTTPubRec, OnMQTTPubRel and OnMQTTPubComp. If you want a call that blocks until the broker confirms, use PublishAndWait, which returns a Boolean and takes a timeout that defaults to ten seconds.
The third parameter of Publish is a TmqttQoS, declared in sgcWebSocket_Types.pas with the members mtqsAtMostOnce, mtqsAtLeastOnce, mtqsExactlyOnce and mtqsReserved. It defaults to mtqsAtMostOnce. Subscribe takes the same type as its second parameter.
Yes. sgcWebSocket_Protocol_MQTT_Client.pas carries no unit-scope platform guard, the only conditional in its uses clause is the Windows import, and the palette component is registered with ComponentPlatforms(0), so the IDE does not restrict its target platforms.
Yes. Set MQTTVersion on the protocol component. The 5.0 property objects are then in play: ConnectProperties on the way out, and the properties parameter on each event on the way back, for example TsgcWSMQTTCONNACKProperties on OnMQTTConnect and TsgcWSMQTTPUBLISHProperties on OnMQTTPublish.
Best value: All-AccessEvery eSeGeCe product, Premium Support included, from €1,059/year.
See All-Access pricing

Ready to put a broker behind your application?

Download the trial and run the MQTT demo against the public test broker.