It would be great to have support for websocket transport in MQTT
Many MQTT brokers allow for connections over websocket (Amazon IoT, HiveMQ, Mosquitto) - in NodeMCU we have modules for mqtt and websocket, so adding support for websocket transport in mqtt shouldn't be very difficult.
Currently I successfully connect to Amazon's MQTT websocket gateway using my own simple mqtt library written in lua, but it is far from complete and probably uses a lot more resources than mqtt module.
I fail to understand why this would be a useful addition to our MQTT module. Can you elaborate?
In my understanding MQTT over websockets (i.e. over HTTP/HTTPS) only makes sense if you want to connect to a broker from a client that can't talk MQTT natively. The one use case that comes to mind is talking to a broker from within a browser with JavaScript.
If you write a NodeMCU app in Lua you shouldn't need to care about how the NodeMCU MQTT module talks to the broker behind the scenes, right?
Anecdotal, but this same thing was requested of me about six months ago from our architects. The scenario that the server folks wanted to support was to host the MQTT broker as a PaaS web application (if you're familiar with Azure App Service, for example... where web traffic is permitted on 80/443, but no other arbitrary TCP port ranges). They also had concerns about MQTT 1883/8883 port traffic not being permitted through customer firewalls.
When I looked into it, NodeMCU did not yet have websocket support. Even so, I had concerns about memory issues. I'm not sure that it would be a trivial task for someone to implement (but I have been proven wrong many times before).
We ultimately just went the pure TCP MQTT route and stood up VMs for the brokers in AWS - but MQTT over Websockets is still on our product firmware wishlist, maybe in a future ESP32 timeframe.
@marcelstoer Concrete case: Amazon's MQTT broker requires client certificate authentication with TLS 1.2 - NodeMCU doesn't support that. Other useful case mentioned by @jfollas above - firewall permitting only HTTP/HTTPS traffic.
@jfollas - we can rewrite MQTT to use net / websocket sockets (clients) internally, instead of raw esp_conn. This may even simplify current implementation a bit (grep for CLIENT_SSL_ENABLE in modules/mqtt.c - for SSL connections we have to call different API than for regular connections (esp_secure_connect/esp_connect, esp_secure_send/esp_send, ...)
It can't be a total replacement - any MQTT client would still need to work over TCP since that's the primary use case.
I have zero bandwidth to work on anything like this, but can lend a hand with testing if and when that time comes.
I can see mqtt over websockets as a possible way to connect to AWS IoT. I would really love if the ESP (8266) on Lua could support AWS IoT security requirements. As far as I know, there is NO current way to connect to AWS IoT via MQTT over TCP... I had to increase the SSL MAX LENGTH to 5100 to prevent the handshake sequence from failing early ...but after going through the mbedtls certificates sequence, it fails with E:M out of memory (~250 bytes)...looks like we are close to make it work but not quite there yet...so unless someone can make the ESP8266 connect to AWS IoT, I see possible hope that it would work over websockets since AWS IoT in this case doesn't require client certs, only root CA...maybe a flow less RAM hungry. I tested Mongoose OS and they support client certs + CA to AWS IoT on the ESP8266. Not sure how they do it but it works ! So if they can do it, there is hope we can do it unless LUA implement is more RAM hungry than Mongoose OS. (though I haven't tried LFS yet to see if it would help)
@mrk-its Can you share the code you used to connect to AWS IoT via websockets ? thx !
I was able to get this to work and communicating with AWS IoT using a modified version of @mrk-its code linked above. Thanks!
On the latest NodeMCU 2.2.1 build, the trick for me was to set SSL_BUFFER_SIZE to 5376 so the initial TLS 1.2 handshake would work.
One downside of this approach is that AWS IoT authentication via websockets requires AWS Signature v4, meaning that the AWS access key and secret key need to be stored on the device to generate the signature upon initial connection. Any suggestions on how to securely store/distribute these AWS keys on devices out in the wild to end users?
I suspect that this is the answer: https://docs.aws.amazon.com/iot/latest/developerguide/authorizing-direct-aws.html
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Most helpful comment
@marcelstoer Concrete case: Amazon's MQTT broker requires client certificate authentication with TLS 1.2 - NodeMCU doesn't support that. Other useful case mentioned by @jfollas above - firewall permitting only HTTP/HTTPS traffic.
@jfollas - we can rewrite MQTT to use net / websocket sockets (clients) internally, instead of raw esp_conn. This may even simplify current implementation a bit (grep for CLIENT_SSL_ENABLE in modules/mqtt.c - for SSL connections we have to call different API than for regular connections (esp_secure_connect/esp_connect, esp_secure_send/esp_send, ...)