Andrew Spencer 2 Posted September 8 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 677 Posted September 8 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 September 11 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 September 11 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 677 Posted September 11 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 September 11 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 677 Posted September 11 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
Andrew Spencer 2 Posted 7 hours ago I have my simple TIcsMQTTClient-based app working on Windows in a test console application, using the above advice. Instead of using FMQTTCli.LinkSocket.MessageLoop which is blocking, I call the following procedure, which could allow future expansion and better control procedure RunMessageLoop; var Msg: TMsg; begin while GetMessage(Msg, 0, 0, 0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end; My main problem now is that I need to get this running on both Windows and Linux platforms, and I see that ICS does not (yet?) support Linux. (I thought that FMX meant Linux support, and did not read the fine print!) Any suggestions? Share this post Link to post
Angus Robertson 677 Posted 4 hours ago No ICS has never been supported on Linux. In practice, the functions that don't require messages do work now, there is a sample IcsPemTest that runs on Linux, I did spend several weeks working on ICS v10 with a new cross platform message engine, but hit a compiler problem with derived components, and ICS has a lot of those. So a lot of v10 needs rewriting, not had time. I may get back to it this winter. Angus Share this post Link to post