Mqtt.js: WebSocket connection to 'ws://test.mosquitto.org/' failed: Error during WebSocket handshake: Unexpected response code: 200

Created on 1 Jun 2017  ·  23Comments  ·  Source: mqttjs/MQTT.js

When I use it on browser,

var client = mqtt.connect('mqtt://test.mosquitto.org') // you add a ws:// url here

I just can not connect the server, and got this error:

VM8520:37 WebSocket connection to 'ws://test.mosquitto.org/' failed: Error during WebSocket handshake: Unexpected response code: 200

Most helpful comment

There is no way for JavaScript running in browsers to open TCP sockets so "normal" MQTT is impossible in browser apps. To get around this limitation, MQTT.js uses MQTT over WebSockets instead when it detects it's running in a browser.

So what you're seeing is how MQTT.js is supposed to work in browser apps. If your broker doesn't support MQTT over WebSockets, you need to find another way to communicate with it.

To use test.mosquitto.org, you need to be explicit about the port since they run their WebSocket endpoints on non-standard ports. I would be explicit about the protocol, too, and use this URL: wss://test.mosquitto.org:8081

However: the WebSocket endpoints on test.mosquitto.org have been broken for a few weeks now. I tried to bring attention to it in their IRC channel. We have no ability to fix it.

Downloading and configuring mosquitto to use WebSockets and run on your local machine isn't too hard. You might want to consider doing that instead of relying on their public test broker. Even when it works, it's very slow. Not to mention insecure.

All 23 comments

As per https://test.mosquitto.org/, mosquitto test server for websockets is on port 8080.

@mcollina this is not a satisfying answer. Why is mqtt turning it into a ws:// address, when it is mqtt? Why does it matter which protocol I use, when it is always transformed?

if you are using a browser, mqtt is translated to ws, because we can't open a TCP socket in the browser. Possibly a bug on my side, if you would like to change that, feel free to open a PR.

Thanks for the reply!
So if my broker runs over mqtt:// I can't access it from the browser?

@MartinMuzatko exactly.

I'm using mqttbox (chrome extension: https://chrome.google.com/webstore/detail/mqttbox/kaajoficamnjijhkeomgfljpicifbkaf) to test my connection. Here I have configured mqtt:// and I can successfully publish and and subscribe.
I tried to debug the app to find out how they convert the mqtt protocol to ws with no success.

Looks like they are sending the publish to a service worker. Do they support mqtt://?

No, service workers can't open TCP sockets. Nor can Chrome extensions to my knowledge.

The instructions for installing MQTTBox say to install an external program. I suspect the extension is communicating with that to get around the browser limitations.

If you want to use MQTT from a "normal" browser-based app, you _must_ tunnel MQTT over WebSockets so your broker will have to support that.

Ok, thank you a lot for clarifying this @jdiamond :)

My broker supports that. Hence this solution works:

import * as io from 'socket.io-client';

const client = io('http://localhost:5000');
client.on('connect', ()=>{
    client.emit('subscribe', {topic: 'OT'});
})

client.on('mqtt', (event)=>{
    // event.topic
    // event.message
})

Is there a way to workaround this problem without using socketio directly? I'd loved to use mqtt on client and serverside.
Unfortunately, using the mqttjs package on the client does not work. Or is there a special setting to "tunnel" mqtt through ws?

I use MQTT.js directly without Socket.IO in multiple apps. I don't remember having to workaround anything. My broker supports WebSockets and the URL I use in my apps start with "wss:". Everything just works.

What broker are you using? How are you building your project? Webpack or Browserify?

@jdiamond Can you provide a sample of how you're subscribing using only MQTT.js? I'm having the same issue as @MartinMuzatko where MQTT.js automatically resolves mqtt://test.mosquitto.org to ws://test.mosquitto.org on a node app running on a browser.

There is no way for JavaScript running in browsers to open TCP sockets so "normal" MQTT is impossible in browser apps. To get around this limitation, MQTT.js uses MQTT over WebSockets instead when it detects it's running in a browser.

So what you're seeing is how MQTT.js is supposed to work in browser apps. If your broker doesn't support MQTT over WebSockets, you need to find another way to communicate with it.

To use test.mosquitto.org, you need to be explicit about the port since they run their WebSocket endpoints on non-standard ports. I would be explicit about the protocol, too, and use this URL: wss://test.mosquitto.org:8081

However: the WebSocket endpoints on test.mosquitto.org have been broken for a few weeks now. I tried to bring attention to it in their IRC channel. We have no ability to fix it.

Downloading and configuring mosquitto to use WebSockets and run on your local machine isn't too hard. You might want to consider doing that instead of relying on their public test broker. Even when it works, it's very slow. Not to mention insecure.

Thanks for the explanation. I was going about it incorrectly and subscribing via the clients rather than the server. MQTT.js works perfectly on the server.

following is the right code to show in my browser ( but if you choose to use mqtt nodeJS API in server, no need...)

// Connect to the MQTT Broker over WebSockets
// The port here is the "http" port we specified on the MQTT Broker
var client = mqtt.connect("wss://test.mosquitto.org:8081");

// Message recieved

setTimeout(() => {
  client.publish("TopicToSubscribe", "Hello world!");
}, 1000);

client.on("message", (topic, payload) => {
  // Log message
  console.log(topic);
  console.log(payload);
  // Close the connection
  client.end();
});

client.on("connect",  () => {
  client.subscribe("TopicToSubscribe");
  console.log("Connected to MQTT Broker.");
});

根据https://test.mosquitto.org/,用于websockets的mosquitto测试服务器位于端口8080上。
111111111111111

同样的问题,请问,你们是怎么解决的
WebSocket connection to 'ws://test.ai.babateng.cn:1883/' failed: Connection closed before receiving a handshake response

@1215708470 please use Websockets Port (TLS only), not orginal port!

For anyone else who comes across this: if you are using Mosquitto as your broker, you can use the mqtt protocol by default for application-to-server connections, and then add an extra listener in the _mosquitto,conf_ file to listen on the websockets protocol.

The obvious benefit here is that if, like me, you have a home automation system where the devices communicate over mqtt, you can write a browser-based app to pull dasta for each device into a dashboard.

HTH

and then add an extra listener in the _mosquitto,conf_ file to listen on the websockets protocol.

@webtop What is that extra line that I need to add. I'm trying to get something working in my Home Assistant setup that will work, but it seems it only allows for TCP ports?

and then add an extra listener in the _mosquitto,conf_ file to listen on the websockets protocol.

@webtop What is that extra line that I need to add. I'm trying to get something working in my Home Assistant setup that will work, but it seems it only allows for TCP ports?

That should be fine. The default port for MQTT is 1883 (8883 for secured connections). You can use a hostname or IP address for the listener.

See: https://mosquitto.org/man/mosquitto-conf-5.html

For anyone else who comes here, if you are using mosquitto, it requires you to set up the following in a config file that is loaded by the service.

listener 1883
protocol mqtt

listener 1884
protocol websockets

@bretterer How I can set these configurations that you've said in a WebClient Paho JS ?

I asked you this because I'm trying to connect on test.mosquitto.org with Paho Web Client JS but I'm not gotting success.

Here is my code:

//MQTTT variable
var mqtt;
var reconnectTimeOut = 2000;
var host = "test.mosquitto.org";
//var host = "iot.eclipse.org";
//var port = 8080;
//var port = 8081;
//var port = 1883;
var port = 1884;
//var port = 8883;
//var port = 9001;

function onConnect() {
  console.log("Connected");
  mqtt.subscribe("controlproject/temperature");
}

function onMessageArrived(msg) {
  let temperature = parseInt(msg.payloadString);
  let today = new Date();
  let time =
    today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
  console.log(time, temperature);
}

function MQTTConnect() {
  console.log("Connecting to " + host + " in port " + port);
  mqtt = new Paho.MQTT.Client(host, port, "webpage");
  mqtt.onMessageArrived = onMessageArrived;

  var options = {
    useSSL: true,
    timeout: 3,
    onSuccess: onConnect,
    onFailure: onFailure
  };

  mqtt.connect(options);
}

function onFailure(msg){
    console.log("Connection Attempt to Host " + host + " Failed");
    setTimeout(() => {MQTTConnect();}, reconnectTimeOut);
}
MQTTConnect();

Any one could help me ? I've tried many ports and in which one I got different errors, timeout, refused connection... This web page is running my code through a server with SSL. So, this is websocket over SSL.

Thanks guys!

Client(client_id="", clean_session=True, userdata=None, protocol=MQTTv311, transport="tcp")

So if you want to use websockets in Paho, set the "transport" parameter to "websockets", otherwise leave it blank for the default "tcp"

Thanks a lot for your explanation Paul!

On Sat, Feb 6, 2021 at 10:00 PM Paul Allsopp notifications@github.com
wrote:

Client(client_id="", clean_session=True, userdata=None, protocol=MQTTv311,
transport="tcp")

So if you want to use websockets in Paho, set the "transport" parameter to
"websockets", otherwise leave it blank for the default "tcp"


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/mqttjs/MQTT.js/issues/628#issuecomment-774568993, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AHG7RC3XGEMI27VCUK42CL3S5XQZ5ANCNFSM4DNR3V4A
.

--
Lucas Guimarães da Rocha
cel: (32) 98809-4352

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hijklmno picture hijklmno  ·  7Comments

mcollina picture mcollina  ·  8Comments

DavidMG01 picture DavidMG01  ·  4Comments

sublimator picture sublimator  ·  8Comments

bicccio picture bicccio  ·  3Comments