Recently i’m working on IOT project that needs to send data from ESP32 development board to web browser and mobile devices using MQTT protocol. The MQTT connection between the board and other clients didn’t have problems using standard/native MQTT protocol, but it came into problem when the client was a web browser. The standard MQTT protocol doesn’t work with Eclipse Paho Javascript library which works on top of websocket protocol.
WebSocket connection to ‘ws://123.11.11.11:8883/mqtt’ failed: Connection closed before receiving a handshake response
The above error message was from javascript library when i tried to connect MQTT server that didn’t support websocket. My previous MQTT server was installed with Mosquitto running on Freebsd and it worked well with standard MQTT connection. The standard installation of Mosquitto didn’t support websocket so i had to install additional libwebsocket library and recompiled the Mosquitto.
So here are the requirements and steps to upgrade or setup MQTT server with websocket support using Mosquitto on a FreeBSD server:
Requirements:
- Mosquitto 1.6.2, (latest stable version )
- Libwebsocket-2.4.2, (latest stable version)
Installation:
Libwebsocket
Install libwebsocket from Freebsd ports
#cd /usr/ports/net/libwebsockets
Check the version (2.4.2) (view the distinfo file), if you have old version then backup the libwebsockets port directory
#mv libwebsockets libwebsockets.old
Download and extract the libwebsocket port file
#wget http://www.londatiga.net/downloads/iot/libwebsockets-ports-2.4.2.tar.gz
#tar -xzvf libwebsockets-ports-2.4.2.tar.gz
#cd libwebsockets
Compile and install
#make
#make install
If installation succes, make sure these files exist:
/usr/local/lib/libwebsockets.so
/usr/local/lib/libwebsockets.so.12
/usr/local/include/libwebsockets.h
Mosquitto
Download and extract the source file
#wget https://mosquitto.org/files/source/mosquitto-1.6.2.tar.gz
#tar -xzvf mosquitto-1.6.2.tar.gz
#cd mosquitto-1.6.2
Edit config.mk file to enable websocket. Replace the line WITH_WEBSOCKETS:=no with WITH_WEBSOCKETS:=yes
Copy libwebsocket header files into src directory
#cp /usr/local/include/libwebsockets.h src
#cp /usr/local/include/lws_config.h src
#cp /usr/local/include/uv* src
#cp /usr/local/include/ev.h src
#gmake
#gmake install
Troubleshouting:
You may find some errors while compiling and installing mosquitto, here are some issues:
Issues with openssl:
This issue due to incompatible openssl version, mosquitto 1.6.2 requires openssl >= 1.0.2, so you may get this error messages while compiling:
../lib/libmosquitto.so.1: undefined reference to `SSL_CTX_set_alpn_protos
The solution is to lower the version of mosquitto, you can use version 1.5.8.
Issues with linking dynamic library lwebsockets
/usr/bin/ld: cannot find -lwebsockets
This issue due to the compiler doesn’t find the libwebsockets.so shared library, the solution is to create symbolic link from /usr/local/lib/libwebsockets.so to /lib/libwebsockets.so
#ln -s /usr/local/lib/libwebsockets.so /lib/libwebsockets.so
Issues while installing (gmake install)
install -m644 ../libmosquitto.pc.in “/usr/local/lib/pkgconfig/libmosquitto.pc”
sed -i -e “s#@CMAKE_INSTALL_PREFIX@#/usr/local#” -e “s#@VERSION@#1.5.8#” “/usr/local/lib/pkgconfig/libmosquitto.pc”
sed: -e: No such file or directory
This issue due to invalid sed -e command while trying to replace the CMAKE_INSTALL_PREFIX and VERSION on /usr/local/lib/pkgconfig/libmosquitto.pc file. I’m not expert on sed command, so my solution is to edit this two files two Makefiles:
- lib/Makefile
- lib/cpp/Makefile
find this line:
sed -i -e “s#@CMAKE_INSTALL_PREFIX@#${prefix}#” -e “s#@VERSION@#${VERSION}#” “${DESTDIR}${libdir}/pkgconfig/libmosquitto.pc”
Remove the -e “s#@CMAKE_INSTALL_PREFIX@#${prefix}#” section so the result would be:
sed -i -e “s#@VERSION@#${VERSION}#” “${DESTDIR}${libdir}/pkgconfig/libmosquitto.pc”
Then run #gmake install again and after successfully installing, don’t forget to update the /usr/local/lib/pkgconfig/libmosquitto.pc file, replace the @CMAKE_INSTALL_PREFIX@ with /usr/local.
Setting up Mosquitto
Create a user to run mosquitto, we use mosquitto as the username with nologin and nonexistent options.
#adduser
Username: mosquitto
Full name: Mosquitto MQTT Broker
…..
Shell (sh csh tcsh git-shell nologin) [sh]: nologin
Home directory [/home/mosquitto]: /nonexistent
Change ownership of the directory /var/lib/mosquitto/mosquitto.db to mosquitto (if not exist, create new one)
#chown mosquitto /var/lib/mosquitto/mosquitto.db
Create a file log /var/log/mosquitto.log
#touch /var/log/mosquitto.log
#chown mosquitto /var/log/mosquitto.log
Create http dir for websocket
#mkdir /var/lib/mosquitto/http_dir
#chown mosquitto /var/lib/mosquitto/http_dir
Create username and password for MQTT authentication
#mosquitto_passwd -c /etc/mosquitto/pwfile lorenz
Password:
Reenter password:
Replace the ‘lorenz‘ with your username.
Create the configuration file /etc/mosquitto/mosquitto.conf and use the following configuration
listener 9001 xx.xx.xx.xx
protocol websockets
socket_domain ipv4
http_dir /var/lib/mosquitto/http_dir
listener 8883 xx.xx.xx.xx
protocol mqtt
persistence_location /var/lib/mosquitto/
persistence_file mosquitto.db
log_dest syslog
log_dest stdout
log_dest topic
log_dest file /var/log/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information
connection_messages true
log_timestamp true
allow_anonymous false
password_file /etc/mosquitto/pwfile
user mosquitto
Here, we use port 9001 for MQTT over websockets and 8883 for standard/native MQTT. Replace the xx.xx.xx.xx with your hostname or ip address. You can use whatever port number as you like as long as the number isn’t being used by other service or application.
Run the mosquitto service
#mosquitto -c /etc/mosquitto/mosquitto.conf
You should see these messages on starting up:
1559210145: mosquitto version 1.5.8 starting
1559210145: Config loaded from /etc/mosquitto/mosquitto.conf.
1559210145: Opening websockets listen socket on port 9001.
1559210145: Opening ipv4 listen socket on port 8883.
Based on the above configuration, you should use port 9001 for connection with javascript library on web browser and 8883 on other devices. The message will be automatically forwarded between those ports. So the message that you send on 8883 will also be received on javascript client on port 9001.







Leave a Reply