Andrew Spencer 2 Posted Monday at 10:31 AM I need to use TIcsMQTTClient in a console app (for use in Windows or Linux) I'm battling with the event handling, which seems not to be passing parameters correctly. My initialization code is dynMQTTClient := TIcsMQTTClient.Create(nil); dynMQTTClient.Name := 'dynMQTTClient'; enableMethod.pMethod := @MQTTClientEnableChange; enableMethod.pObject := nil; dynMQTTClient.OnEnableChange := TNotifyEvent(enableMethod); onlineMethod.pMethod := @MQTTClientOnline; onlineMethod.pObject := nil; dynMQTTClient.OnOnline := TNotifyEvent(onlineMethod); messageMethod.pMethod := @MQTTClientMsg; messageMethod.pObject := nil; dynMQTTClient.OnMsg := TMQTTMsgEvent(messageMethod); where each of the xxxxxMethod records is TMethodPointer = packed record pMethod: Pointer; pObject: TObject; end; My handlers are then procedure MQTTClientOnline(Sender: TObject); procedure MQTTClientMsg(Sender: TObject; aTopic: UTF8String; const aMessage: AnsiString; aQos: TMQTTQOSType; aRetained: Boolean); procedure MQTTClientEnableChange(Sender: TObject); But the parameters, when examined inside the routine, are "wrong". e.g. Sender is nil when these events are launched. (I have successfully used the above code method with TTimer and TRESTRequest events) Any ideas/suggestions as to what I might be doing incorrectly? Share this post Link to post
Angus Robertson 672 Posted Monday at 12:48 PM You are trying to use events in an unusual way, without any classes. For console applications, it is best to create a class in which you use and create ICS components, just as with a GUI. Look at the sample OverbyteIcsConHttp;.dpr which creates TConApplication = class(TComponent) with the REST component and it's event. Angus Share this post Link to post
Andrew Spencer 2 Posted Thursday at 02:04 PM Thank you. I have done that, with minor success, using Mosquitto under Docker. On running my simple console application, the TIcsMQTTClient.OnEnableChange gets launched, when expected. I'm unable to get any further events triggering in my console application (attached) although a GUI application (based on the ICS example) works fine. If anyone could try out my source code, and find the problem, it would be very much appreciated! MQTT_Subscriber_Console.zip Share this post Link to post
FPiette 393 Posted Thursday at 02:36 PM 29 minutes ago, Andrew Spencer said: If anyone could try out my source code, and find the problem I looked at your source. I don't see any message loop. That is REQUIRED for ICS component to work. In a GUI application you have one automatically but in a console application you must create one. As Angus said, look at the sample OverbyteIcsConHttp.dprwhich has a message loop. No message loop, no async event... Share this post Link to post
Angus Robertson 672 Posted Thursday at 03:15 PM As François says, you missed the MessageLoop line in OverbyteIcsConHttp. It is commented out because the REST request is synchronous, which means it uses a message loop internally to wait for a response, Angus Share this post Link to post
Andrew Spencer 2 Posted Thursday at 03:20 PM Thanks, both of you. I think that I'm getting the idea of the differences between GUI and console. I've added FMQTTCli.LinkSocket.MessageLoop; To get through the async events, with a FMQTTCli.LinkSocket.PostQuitMessage; to terminate the handling (in the OnOnline event). Since I'm aiming to write an application with API handling and writing MQTT subscriptions into a database, I can see that threads are likely going to be needed sooner rather than later! Share this post Link to post
Angus Robertson 672 Posted Thursday at 05:21 PM BTW, please make sure you are using the latest MQTT component from the overnight zip or SVN, there were major improvements a few months ago that are not yet released, but will be in a day or two. Angus Share this post Link to post