2

I am unable to connect to my local Mosquitto 1.4.10 broker from a JavaScript client over a Websocket.

The same JavaScript client is successfully connecting to the public broker at test.mosquitto.org on port 8080 over a Websocket.

The MQTT protocol connection on port 1883 is working fine, which I tested using mosquitto_pub and mosquitto_sub.

My broker is set up within a VirtualBox running Ubuntu 14.04.

I have libwebsockets installed on the same virtual machine.

My local broker was compiled with WITH_WEBSOCKETS:=yes in the config.mk file

I am loading the JavaScript client web page from the same virtual machine from a Firefox browser and seeing the following error message in the browser console:

Firefox can't establish a connection to the server at ws://localhost:8080/mqtt

Your suggestions on fixing this will be greatly appreciated.

Thanks.

Here is my Mosquitto .conf file:

port 1883
listener 8080
protocol websockets

log_type all
websockets_log_level 1023
connection_messages true

Here is the Mosquitto server's log (with websockets logging level set to 1023, and verbose logging turned on - no messages appear when I load the JavaScript web page):

1481381105: mosquitto version 1.4.10 (build date 2016-12-10 18:47:37+0530) starting
1481381105: Config loaded from /etc/mosquitto/mosquitto.conf.
1481381105: Opening websockets listen socket on port 8080.
1481381105: Initial logging level 1023

1481381105: Libwebsockets version: 2.1.0 manavkumarm@manav-alljoyn

1481381105: IPV6 not compiled in
1481381105: libev support not compiled in
1481381105: libuv support not compiled in
1481381105: Threads: 1 each 1024 fds
1481381105: mem: platform fd map: 4096 bytes
1481381105: Compiled with OpenSSL support
1481381105: Creating Vhost 'default' port 8080, 3 protocols, IPv6 off
1481381105: Using non-SSL mode
1481381105: Listening on port 8080
1481381105: mem: per-conn: 376 bytes + protocol rx buf
1481381105: canonical_hostname = mqtt
1481381105: Opening ipv4 listen socket on port 1883.
1481381105: Opening ipv6 listen socket on port 1883.

Here is the JavaScript source code:

<html>

 <body>
  <script src="mqttws31.js"></script>
  <script>
   try
   {
         // Create a client instance
    console.log("Creating client object...");
    client = new Paho.MQTT.Client("localhost", Number(8080), "manav");
    //client = new Paho.MQTT.Client("test.mosquitto.org", Number(8080), "manav");
     
    // set callback handlers
    console.log("Setting handlers...");
    client.onConnectionLost = onConnectionLost;
    client.onMessageArrived = onMessageArrived;
     
    // connect the client
    console.log("Connecting...");
    client.connect( {
                                  onSuccess: onConnect, 
                                  mqttVersion: 4
                                });
   }
   catch (e)
   {
    console.log("Error: " + e.description);
   }
    
   // called when the client connects
   function onConnect() 
   {
     // Once a connection has been made, make a subscription and send a message.
     console.log("Connected");
     setTimeout( function() {
      client.subscribe("world");
      message = new Paho.MQTT.Message("Hello");
      message.destinationName = "world";
      client.send(message);
      //client.disconnect();     
     }, 5000);
   }
    
   // called when the client loses its connection
   function onConnectionLost(responseObject) {
     if (responseObject.errorCode !== 0) {
       console.log("Connection lost: " + responseObject.errorMessage);
     }
   }
    
   // called when a message arrives
   function onMessageArrived(message) {
     console.log("Received Message: " + message.payloadString);
     client.disconnect();
   }

   </script>

  <h1>My MQTT Websockets Example</h1> 

 </body>

</html>
Manav
  • 21
  • 1
  • 4
  • 1
    where is the browser is running in host or inside virtualbox ? – Renjith Thankachan Dec 10 '16 at 15:21
  • Inside the same VirtualBox where Mosquitto is running. – Manav Dec 10 '16 at 15:24
  • @Manav by "Inside the same VirtualBox" do you mean to say inside the same virtual machine? Because if they different virtual machines inside the same virtualbox program then things will be different. – sid-m Dec 10 '16 at 15:28
  • Yes, inside the same virtual machine - sorry about the lack of clarity in my earlier response. – Manav Dec 10 '16 at 15:31
  • Edited the original post for clarity. – Manav Dec 10 '16 at 15:34
  • Looks like no IPv6 on the Websockets, as a quick test change localhost to 127.0.0.1 in the `Paho.MQTT.Client()` – hardillb Dec 10 '16 at 15:55
  • I get the same result after changing localhost to 127.0.0.1, 127.0.1.1 or the IP Address of my virtual machine. – Manav Dec 10 '16 at 16:00
  • Is there any significance to IPv6 not having been compiled with Mosquitto or libwebsockets? – Manav Dec 10 '16 at 17:08
  • I found some comments on a raspberry pi blog that suggest that mosquitto assumes libwebsockets.so is available at another system path: "To publish messages by means of "mosquitto_pub" command, you need more symlinks: root@rpi2:~# ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1 Now the following command will send message to client's web browser: root@rpi2:~# mosquitto_pub -u username -P password -t /World -m "test message from shell"" – Ashish Dec 11 '16 at 04:50
  • Thanks, I just tried that but it didn't work. And I think this should already have been taken care of when I added /usr/local/lib to lib64c.conf and libc.conf and ran sudo ldconfig. – Manav Dec 11 '16 at 06:47

1 Answers1

2

I see I am little bit late on answer.

MQTT's port for websocket is 1884 or something else, you have 8080. Maybe thats the problem.

Isnt 8080 a reserved TCP port?

Also, I know you have javascript code, but its paho. I was able to make publisher(it uses same class like subscriber so it must be on subscriber side too - this is just assumption though) work on websockets with paho python client which must be initialized with defining transport parameter. -> communicating with browser(see below for javascript)

mqtt.Client(transport='websockets')

Leaving that parameter MQTT assumes using TCP

mqtt.Client()

Also:

Config on my broker:

# Place your local configuration 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.pid

persistence true
persistence_location /var/lib/mosquitto/

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

include_dir /etc/mosquitto/conf.d

listener 1883
listener 1884
protocol websockets

I found my very old Javascript with paho-mqtt. It was working, so I just put it here. Its subscriber and publisher at the same time. Together with the config, It was working like charm.

class sub{
  constructor(hostname,port,clientid,topic){
    this.buffer = []

    this.hostname=hostname;
    this.port=port;
    this.clientid = clientid;
    this.topic = topic;
    this.client = new Paho.MQTT.Client(hostname,port, clientid);
    // set callback handlers
    this.client.onConnectionLost = this.onConnectionLost;
    this.client.onMessageArrived = this.onMessageArrived.bind(this);
    // connect the client
    this.client.connect({onSuccess:this.onConnect});
                                         }
onConnect(){
  console.log('OnConnect');
}

onConnectionLost(responseObject) {
  if (responseObject.errorCode !== 0) {
    console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
onMessageArrived(message) {
  console.log("onMessageArrived:"+message.payloadString);
  this.buffer.push(JSON.parse(message.payloadString));


}


subsribe(){
this.client.subscribe(this.topic)
}
publish(message){
console.log(message)
var mg = new Paho.MQTT.Message(JSON.stringify(message));
mg.destinationName = this.topic;
this.client.send(mg);
}


}
var x
x = new sub('xx.xx.xx.xx',1884,'clientID','LED');

function on(){

x.publish({'LED':'ON'});
}
function off(){

x.publish({'LED':'OFF'});
}
Martin
  • 3,333
  • 2
  • 18
  • 39
  • The OP has configured port 8080 and is using port 8080 in the code – hardillb Jan 21 '19 at 22:40
  • Ah my bad. But maybe that's why it doesn't work. Isn't 8080 a reserved Tcp port? – Martin Jan 21 '19 at 22:50
  • No, you can use any port (not currently in use by another app) above 1024 as a normal user and it would have thrown an error if the port was in use – hardillb Jan 21 '19 at 23:18