LabVIEW MQTT: Error 66 when reading subscribed topics - mqtt

For the past month, I have been working on two MQTT clients that will communicate with each other over a CloudMQTT broker.
The clients use the DAQIO LabVIEW MQTT library (found here https://github.com/DAQIO/LVMQTT). The basic operation is that one client (LaptopClient) will publish commands to the other client (USBClient), which will read the command, perform an action, and publish a message back to the origin.
The problem occurs when USBClient is unable to read the command. When USBClient is initialised and is waiting for LaptopClient to send a command, and LaptopClient sends a command, the "read subscribed topics" function of USBClient will present error 66, saying that the connection was closed.
What I've tried:
Using a local broker, instead of CloudMQTT
This resulted in no error, but I cannot use a local broker for the final product because I will not be able to connect from another computer over a wireless network.
Replacing LaptopClient's publish with mosquitto_pub (isolating USBClient)
This resulted in no error, USBClient was able to read the command and publish an acknowlegement.
Replacing USBClient's subscribe with mosquitto_sub (isolating LaptopClient)
This resulted in no error, LaptopClient was able to publish the command successfully.
Connecting to my phone's mobile hotspot
I tried this because I thought there might have been an issue with the network. It resulted in error code 1, which states that an input parameter was invalid. However, the only input parameter was the connection ID.
Replacing LaptopClient with default test client provided by DAQIO LabVIEW MQTT Library
I tried this to eliminate issues with the library. It resulted in no error.
It does not make sense to me, why does it work over a local broker but not online?
As you can see, the error occurs after reading the subscribed topics. Why does it work when either of the clients are replaced?

Related

"would like to find and connect to devices on your local network" error with inbound CFSocket connection

We have an IOS application which only listens on a INADDR_ANY socket connection for inbound connection using CFSocketCreate/CFSocketGetNative/CFSocketCreateRunLoopSource/CFStreamCreatePairWithSocket etc (to display debug information via HTTP).
(So it falls into the category "Listening for and accepting incoming TCP connections").
If the first incoming socket connection happens on a new installed app we run into the error mentioned above. As we do neither use Bonjour nor getpeername() I wonder where the problem is. Obviously it doesn't matter how the dialog is closed, our program works. But it is of course annoying for us (QA is harder) and our customers.
Any idea what could be the problem ?
I looked into all the questions related here, but I think we are not using one of the 'banned' APIs triggering the dialog
If I set a breakpoint to the stream:handleEvent: function of the NSStreamDelegate the popup appears before NSStreamEventOpenCompleted, so it appears some internals of the NSStream processing cause this.
on the debug console this appears btw:
[connection] nw_connection_copy_connected_path [C1] Client called nw_connection_copy_connected_path on unconnected nw_connection 2022-04-06 17:28:55.811551+0200 GenMob[35630:3181485] [] tcp_connection_is_cellular No connected path
I did fiddle together a small demo app downloadable from https://github.com/leopatras/cfsocket.
For the record, we ended up rewriting our code to use plain Berkeley sockets together with the GCD dispatch_source machinery ... there is a working socket server sample not triggering the local network prompt at https://github.com/leopatras/GCDSimpleSocketServer/
The dispatch_source_zzz functions allow a similar event driven approach like the CFStreamCreatePairWithSocket function. In comparison to https://github.com/leopatras/cfsocket it needs even less code. If the local network prompt is always triggered is questionable, it may depend from other parameters such as the used dev certificate/provisioning profile.
I had an intensive exchange with the Apple support about this topic,
(they weren't able to reproduce our problem initially, but after retrying on several devices they got it too) : they did recommend using the new Network framework functions instead of Berkeley sockets (See https://developer.apple.com/documentation/network?language=objc) and I tried hard to use them however I failed to create a simple reliable working echo server with those functions in obj-C (didn't try the Swift route).

Self bridging Mosquitto MQTT broker

I am trying to self-bridge a mosquitto broker. Let me explain the scenario for which I am doing this.
We have 2 parts to our application. One which is concerned with processing data and other is a modbus service that reads data from PLC devices.
The processing part of the application is capable of handling multiple clients. I want to setup a test and a production tenant for the same client. The reason behind this is that this would give our clients the liberty to play around with the test tenant where as the production won't be affected by this.
The test client both sends as well as receives data from the broker. It is important that we don't send the test tenant's data to our modbus service. The topics follow the following format.
company/service/test/+ for the test client and company/service/prod/+ for the prod client.
The modbus service send data to the same broker in the format company/service/prod/+.
Is there a way for me to remap this topic to company/service/test/+ so that both test and prod clients can receive data from the broker.
address 127.0.0.1:41888
topic /company/values/prod/+ in 2
topic /company/values/prod/+ out 2 "" /company/values/test/+
remote_clientid test
remote_username mqttuser
remote_password broker-123
Remember I have a single broker instance and I'm trying to self bridge on this.
In my above configuration, the remapping doesn't happen cause it's not a valid prefix.
Can someone please help me figure out how to approach this?
The problem is the + on the end of the output topic mapping in
topic /company/values/prod/+ out 2 "" /company/values/test/+
You want
topic + out 2 /company/values/prod/ /company/values/test/
This will strip off /company/values/prod/ and replace it with /company/values/test/
You also want to remove the first topic line (topic /company/values/prod/+ in 2 ) as this will lead to an infinity publish loop for any message published to /company/values/prod/+
p.s. starting topics with a leading / while valid in the spec is a REALLY bad idea, as it breaks things when you get round to needing shared subscriptions and injects an unneeded null to the start of every topic.

Why does MQTT acknowledge so slow?

I wrote an MQTT client program, which runs at a computer (computer 1). The MQTT client program connects to an MQTT Broker with QoS=1 and publishes data to Broker periodically. I subscribe the Broker (Qos=1) from another computer (computer 2), using Mosquito utility. I found the data published to Broker will be delay delivered to publisher about 3 seconds. The delayed time is too long. I checked the codes and found the 3-second-delay time is from read_packet() which is to read back acknowledge from Broker. Why is there such long delay time? How can I figure it out? The Broker (MQTT server) is managed by my coworker. If the Broker is the cause, I can request them to help. But I need to know what could be the trouble source, so that I can check with them.
I can confirm the delay occurring at the time of reading back acknowledge from Broker by watching the debugging message from MQTT client program at computer 1. For Qos = 1, the client must read back acknowledge after sending (publishing) packets. I found 3-second delay time between sending packet and reading back acknowledge. Surely, I also found the delay at display of Mosquito_sub utility.
Assuming near instant network comms and nothing else strange going on the fact that you have recreated the problem with mosquitto_sub then this points to the MQTT broker being the source of the problem.
Without knowing what broker you are using and how heavily it is loaded it's hard to say more but you should look at the broker logs.

Sending MQTT messages to Orion Context broker

I have a relatively simple switch that sends data whenever the button is pressed (either 1 or 0). The message protocol it uses is MQTT. It is connected to Mosquitto via Wi-Fi and successfully sends data to it (i am able to see it using mosquitto_sub -v -t "#". However, I would like to be able to send this data to Orion Context Broker and then receive it using REST commands and store it using Fiware-Cygnus afterwards.
the topic that sensor publishes messages to is tt/sergo/demo/sw
the name of the sensor presented in mosquitto_sub when sensor is first connected: DMS-A01
the IP - address of sensor: 192.168.0.108
I have installed Iot-Agent UL, which is working, but I don't know how to make it listen to the specific sensor that sends data to Mosquitto.
I read the manuals but either missed something or did not find the solution to my problem.
I tried using the manual below, but could not apply it to my problem.
Connecting "thing" to Fiware
Thank you in advance, stack overflow community.
Before sending measures you need to do a provision operation for the device using the IOTA-UL API. That provision operation "creates" the device in the IOTA-UL and map it with the corresponding entity at CB. Then, you can start sending measures using MQTT.
You can have a look to this piece of documentation for more detail.

Mosquitto fire only one for each topic

I implemented a MQTT message broker using mosquitto on my network. I have one web app publishing things to the broker and several servers that subscribed the same topic. So i have a redundancy scenario.
My question is, using mosquitto alone, is there any way to configure it to publish data only on the first subscriber? Otherwise, all of them will do the same thing.
I don't think that is possible.
But you can do this.
Have the first subscriber program respond with an ack on the channel as soon as it gets the message, and have the redundancy program look for the ack for a small time after the initial message.
IF the ack is received the redundancy should not do anything.
So if the first subscriber gets and uses the message, the others wont do anything even if they get the message.
No this is not possible with mosquitto at the moment (without communication between the 2 subscribers as described in the other answer).
For the new release of the MQTT spec (v5)* there is a new mode called "Shared Subscriptions". This allow s multiple clients to subscribe to a single topic and messages will be delivered by round robin to each client. This is more for load balancing rather than master/slave fail over.
*There are some brokers (HiveMQ, IBM MessageSight) that already support some version of Shared Subscriptions at MQTT v3.1.1, but they implement it in slightly different ways (different topic prefixes) so they are not cross compatible.

Resources