Setting up Paho Javascript Client (MQTT) with mosquitto on AWS EC2 Ubuntu + Ruby on Rails

Vic Source

I have been trying to setup a MQTT broker on my AWS EC2 server, using the port 1883. So far it works with the ruby-mqtt gem, but I am having trouble with setting it up with Paho Javascript Client for the website.

What I have done so far:

Mosquitto

Installed mosquitto on my AWS EC2 instance, and it is running and listening on port 1883. I subscribed to a topic locally using the command

mosquitto_sub -h localhost -p 1883 -v -t 'topic1'

AWS EC2 Security Group

Allow traffic over port 1883 (under tcp protocol)

Ruby on Rails

Installed ruby-mqtt gem, and tested the mqtt to be working by running the code below in rails console (development environment)

MQTT::Client.connect(ip_address_or_domain_name) do |c|
  c.publish('topic1', 'message to topic 1')
end

The message appears in the terminal where mosquitto_sub was running.

Nginx

All this was done without any configuration on Nginx configuration files.

Paho Client

So I fired up a local rails server on my local computer, and run the example javascript snippet on one of my html view.

// Create a client instance
client = new Paho.MQTT.Client("mqtt.hostname.com", Number(1883), "", "clientId")

// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;

// connect the client
client.connect({onSuccess:onConnect});


// called when the client connects
function onConnect() {
  // Once a connection has been made, make a subscription and send a message.
  console.log("onConnect");
  client.subscribe("topic1");
  message = new Paho.MQTT.Message("Hello");
  message.destinationName = "topic1";
  client.send(message);
}

// called when the client loses its connection
function onConnectionLost(responseObject) {
  if (responseObject.errorCode !== 0) {
    console.log("onConnectionLost:"+responseObject.errorMessage);
  }
}

// called when a message arrives
function onMessageArrived(message) {
  console.log("onMessageArrived:"+message.payloadString);
}

But I fail to connect. The error I am getting in the chrome developer console is:

WebSocket connection to 'ws://mqtt.example.com:1883/' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET

Im not sure what is wrong here. Greatly appreciate any help! Thanks in advance!

ruby-on-railsmqttpahoruby-mqtt

Answers

answered 2 years ago Vic #1

So the problem is Paho Javascript Client states that the parameter for client object has to be

the address of the messaging server, as a fully qualified WebSocket URI, as a DNS name or dotted decimal IP address.

So making it listen to port 1883, which is the standard port for mqtt, will not work.

ruby-mqtt works as it is because it parameter is treated as a mqtt uri

In other words, Paho connects via ws://host while ruby-mqtt connects via mqtt://host. The latter connects to port 1883 with the correct protocol (not sure if this is the right word here) for the correct port.

So Paho has to connect to another port where the websocket protocol can be used.

This is my solution.

Mosquitto

Version need to be at least 1.4 where websocket is supported. I add the last 3 lines to the default mosquitto.conf file.

# /etc/mosquitto/mosquitto.conf
pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d

port 1883

listener 1884
protocol websockets

This opens 2 ports for mosquitto to subscribe to over 2 different protocols respectively.

AWS Security Group

Allow traffic over port 1884 (under tcp protocol)

Paho Client

mqtt.hostname.com change just the line where the client object is initialized to

client = new Paho.MQTT.Client("mqtt.hostname.com", Number(1884), "", "clientId")

comments powered by Disqus