[fpc-pascal] MQTT package for freepascal/lazarus?

Bo Berglund bo.berglund at gmail.com
Sun Oct 23 15:31:33 CEST 2022


On Sun, 23 Oct 2022 11:51:31 +0200, Bo Berglund via fpc-pascal
<fpc-pascal at lists.freepascal.org> wrote:

>TESTING.....
>No it does not work!
>The mosquitto output cannot be redirected like this because it seems to be
>printed to an output screen which is not redirectable...
>All that happens is that an empty file is created at start of the command and
>then nothing more...

Well, I was wrong, it *does* work if done properly...

First of all, it seems like the call to mosquitto_sub with redirection somehow
opens that file for writing *once* and then you cannot delete that file from the
outside because mosquitto will keep writing to it but now it is invisble to all
others...
This is on an ext4 file system where deleted files still exist such that an
application can keep working with it even when the directory system has lost it.
I have tested this on Ubuntu 20.04 server:

mosquitto_sub -h 192.168.117.131 -F '@Y- at m-@d @H:@M:@S ; %t ; %p' -t '#' >>
mqttlog.txt

And this happens:

- every new message coming in is logged to that file as a new line
- if I delete that file (from another terminal window) then the
  file is *not* recreated when a new message arrives and there is
  no longer any accessible logging. The file still exists, but
  is not visible anywhere else any longer.
- but if I echo a blank to the file (echo "" > mqttlog.txt) then
  the file *contents* gets erased but it accepts new messages.

So the procedure needs to be:
- start mosquitto_cli as shown with >> redirection
- then look for the log file to change size
- open it for read/write
- copy out all the lines
- erase the content and then save the file and close the handle
- it is now an empty file waiting for new data

Then one can process the saved content of the file and do whatever is needed
depening on that.
And finally return to waiting for the file size change again....

All of this can be done with an FPC command line program, I believe.
But...

QUESTION:
---------
It seems like I should not have to start a shell with the mosquitto_cli program
when there is TProcess, which could run it directly and read the data without
using an intermediate log file...

I have found this:
https://wiki.freepascal.org/Executing_External_Programs#Reading_large_output

How should I accomplish the above using TProcess?
- The called application mosquitto_cli must run until my program itself exits
- The data produced by the process should be checked while the process runs
- Using a TMemoryStream to retrieve the output is apparently the way

But how can I handle this situation:
- The incoming data is arriving one msg at a time with seconds in between
- The messages may contain 10-1500 characters each
- How to check that the stream has received all data for one transmission?

Can I do this (using the example from the wiki link above):

// All generated output from AProcess is read in a loop until no more data...
repeat
  repeat
    BytesRead :=  AProcess.Read(Buffer, BUF_SIZE);
    OutputStream.Write(Buffer, BytesRead)
  until BytesRead = 0;  // Stop if no more data is available
  ProcessIncomingMessages(OutputStream);
until 1 //Run forever... How do I get out eventually ??

What happens if the data in the AProcess output stream is less than my buffer
size, will it then stall until as many messages have arrived as will fill the
buffer?

This cannot be allowed to happen because there may be hours before the next
burst of messages.


-- 
Bo Berglund
Developer in Sweden



More information about the fpc-pascal mailing list