mcollina / mows

Using MQTT.js in the browser over WebSocket -- Built with browserify!
72 stars 12 forks source link

Works with HiveMQ; doesn't work with Mosquitto #5

Closed andypiper closed 10 years ago

andypiper commented 10 years ago

Tested https://gist.github.com/andypiper/8667015 against

The code works fine with mqttdashboard which uses HiveMQ on the backend, but not with the other two brokers, which are mosquitto on the backend.

This issue affects https://github.com/cresprit/mqttbot which uses mows for WebSocket support.

ragingwind commented 10 years ago

@andypiper thanks for reporting. It would be great if this issue is resolved.

andypiper commented 10 years ago

yup - I've just forked mqttbot for some changes and wanted to get to the bottom of this :-)

mcollina commented 10 years ago

Mows uses the same parsing logic of MQTT.js, but on a websocket transport instead of TCP. Where you able to identify the problem? My guess is that MOWS is doing something weird on the link. It might be related to the splitting of MQTT messages.

I currently do not have time to debug this. Would you like to help and submit a PR?

Is there an implementation of MQTT over Websocket that works on Mosquitto? I heard that the Paho one was not working on it, but I might be wrong.

andypiper commented 10 years ago

I wonder if this is the thing that was supposed to be patched by the "arbitrary frames" fix on Paho. I will take a look.

andypiper commented 10 years ago

This works - http://www.hivemq.com/demos/websocket-client/

It uses Paho's Javascript client mqttws31.js

andypiper commented 10 years ago

I think this is something to do with the fact that both of the two failing brokers are listening for WebSocket on port 80.

I ran a Wireshark. Running my test app against ws://broker.mqttdashboard.com:8000/mqtt means that the connection gets upgraded to a websocket. Running it against ws://test.mosquitto.org:80/mqtt seems to generate a regular HTTP request which returns a 404 not found (this is what @ragingwind reported in mqttbot as well). Running the Paho Javascript client in a web page against ws://test.mosquitto.org:80/mqtt works correctly and upgrades to a websocket.

My guess is that either the node url parser or mows itself is seeing :80 and treating this as a regular HTTP call regardless of the wss:// prefix on the URL. I haven't dug further than this yet.

mcollina commented 10 years ago

Ok, I make some light progress: I'm confident that the error is not inside MOWS, as using the ws module fails too.

var WebSocket = require('ws');
var ws = new WebSocket('ws://test.mosquitto.org/mqtt');
ws.on('open', function() {
  console.log('WS is open!');
});

This is bad news because it's harder to debug and fix. I'm pulling in @ralight and @3rd-Eden, as they might give some insight of what might going on.

andypiper commented 10 years ago

Yeah, I was just getting to the same conclusion. I took a look at ion-cannon (https://github.com/csquared/ion-cannon) and it looks like it has the same issues. Wireshark indicates that pointing it at the test.mosquitto or m2m.eclipse brokers on port 80 causes a regular non-upgraded HTTP request to be sent to the server.

mcollina commented 10 years ago

Can you check if the WebSocket headers sent by WS are the same that are sent by a browser? Or if there is a difference?

3rd-Eden commented 10 years ago

@mcollina Doing a:

var ws = new WebSocket('ws://test.mosquitto.org/mqtt'); ws.onopen = function () { console.log('open', this ) }

In Google Chromes yields an failed: Error during WebSocket handshake: Unexpected response code: 404. So i'm gonna assume that the server is not handling WebSockets correctly.

mcollina commented 10 years ago

Seems it's @ralight business then.

mcollina commented 10 years ago

Thanks @3rd-Eden!

ragingwind commented 10 years ago

I got a same error with @3rd-Eden on chrome. It might be some of issues in the servers. but HiveMQ Websocket Client and mosquitto WebSockets it works well with ws://test.mosquitto.org/mqtt.

mcollina commented 10 years ago

This is extremely weird.

andypiper commented 10 years ago

Yeah, getting some odd results testing against ActiveMQ with mqtt+ws as well. Works in the browser with Paho client, doesn't work with my mows test app in node. Hmm. Time for some MQTT-over-WebSocket interop tests! :-o

mcollina commented 10 years ago

Should mows send some custom header that it is not sending and HiveMQ do not care?

Can you include Mosca in your testing, too? It uses mows by default.

3rd-Eden commented 10 years ago

It was missing the websocket protocol definition: "mqttv3.1":

var ws = new WebSocket('ws://test.mosquitto.org/mqtt', "mqttv3.1"); ws.onopen = function () { console.log('open', this ) }

works

mcollina commented 10 years ago

Ok, this works in node too:

var WebSocket = require('ws');
var ws = new WebSocket('ws://test.mosquitto.org/mqtt', { protocol: 'mqttv3.1' });
ws.on('open', function() {
  console.log('we are open!')
});
andypiper commented 10 years ago

@mcollina are you able to fix this in mows?

andypiper commented 10 years ago

NB more info on required / should handle for mqtt-over-ws http://wiki.eclipse.org/Paho/Paho_Websockets

mcollina commented 10 years ago

@andypiper should be fixed by #6.

mcollina commented 10 years ago

Thanks @3rd-Eden for finding the issue!!

andypiper commented 10 years ago

Thanks guys for looking into this! :-)

ragingwind commented 10 years ago

great! :+1:

mcollina commented 10 years ago

Released as v0.0.3.

ralight commented 10 years ago

This may also be relevant in case a similar bug pops up in the future:

https://github.com/nori0428/mod_websocket/issues/28

mcollina commented 10 years ago

Thanks @ralight! The main problem with this issue is that it is impossibly hard to debug, as there is little information on what's going on, just a laconic 404. I think that a best practice for brokers might be a different HTTP code instead of 404, or some more debugging things in the response.