MQTT Subscribing with Serverless Function

83 Views Asked by At

We have a project that uses a lidar detector to detect objects within 2 meters. We are wanting to run this on a raspberry pi 4, using open-faas/faasd serverless framework. We are using mosquitto as our MQTT Broker. We have everything running locally on the raspberry pi. We set up the raspberry pi locally as a publisher, and set up a local subscriber and we are successfully seeing the input from the lidar detector. However, when we try to push the same code to open-faas, we are getting connection errors.

We have configured our mosquitto configuration file to listener 1883:0.0.0.0 , and allow_anonymous true . We have tested mosquitto_sub , and it's working successfully. The only problem is when trying to invoke the subscriber function on faasd we are getting an error for connection refused to the mqtt broker while using paho python as our connector. Attached is our code, and error message. Any further troubleshooting tips/insight would be greatly appreciated.

Error: https://imgur.com/M34zmJ0 Link to config file: https://imgur.com/a/iQm6c6i

Link to our code: https://github.com/ggg0241/ServerlessADAS_SD

config file:

#place your local configuration file in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example

pid_file /var/run/mosquitto/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log
log_type all

# include_dir /etc/mosquitto/conf.d

listener 1883 

allow_anonymous true

# password_file /etc/mosquitto/passwords.txt

# acl_file /etc.mosquitto/acl.txt

YAML File for open-faas:

 version: 1.0
provider:
  name: openfaas
  gateway: http://localhost:8080

functions:
  subscriber:
    lang: python3
    handler: ./subscriber
    image: your-docker-hub-username/subscriber:latest
    environment:
      BROKER_ADDRESS: "localhost"
      TOPIC: "lidar/data"

handler.py file for open-faas:

import paho.mqtt.client as mqtt
import time

broker_address = "localhost"  # Use your MQTT broker address
topic = "lidar/data"  # Use your MQTT topic

# This will store the latest message
last_msg = None

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe(topic)

def on_message(client, userdata, msg):
    global last_msg
    last_msg = msg.payload.decode()
    print("Received message: " + last_msg)

client = mqtt.Client()

# Set callback functions
client.on_connect = on_connect
client.on_message = on_message

def handle(req):
    global last_msg
    client.connect(broker_address, 1883, 60)
    client.loop_start()
    time.sleep(1)  # Give the client some time to receive messages
    client.loop_stop()
    client.disconnect()
    return "Last message: " + str(last_msg)
1

There are 1 best solutions below

0
hardillb On
  1. open-faas is running your code in a container, containers get their own TCP IP stack (namespace) so localhost points to the container NOT the host machine it is running on. You MUST use the external IP address of the machine running the broker as the broker address.

  2. If mosquitto is still saying it's running in local only mode then it is NOT running the config file you have provided. Most likely you have not restarted the service since editing the file, but that is just the best guess since you've not provided any other information. The other option is that you are starting mosquitto manually and not providing a path to the config file, mosquitto does NOT have a default file it will read, you must always provide a path to the config file with the -c option.