mqtt之wss。

弄了两天,感觉mqtt中的wss是个大坑,非常不好用,但https网页环境中又必须要用,记录下爬坑过程!

1.需要搭建mqtt服务器,制作证书,搭建nginx,配置wss代理,配置mqtt客户端;

 

2.mqtt服务器选择mosquitto-1.4.4,搭建过程请参考https://blog.csdn.net/u013332124/article/details/79480639(注意要在linux通过源码编译方式安装,由于默认未开启websockets,需要在config.mk文件中开启,再进行编译);

mosquitto安装后需要先配置,才能启动,有这几点:配置启动用户user,mqtt端口,ws端口。

启动(默认安装位置etc/mosquitto):mosquitto -c mosquitto.conf -v

mqtt之wss。_第1张图片

上图中的1883为mqtt端口,3003为ws端口,8883为mqtts端口(添加ssl证书后),3004为wss端口(添加ssl证书后)。

 

3.证书制作使用generate-CA.sh,使用方法请参考https://blog.csdn.net/peakguy/article/details/71634842。

证书分为服务器证书和客户端证书:

mqtt之wss。_第2张图片

rnd185.fro.local(默认服务器域名)开头的都为服务器证书,mqtt18501(手动指定)的为客户端证书。

其中需要用到的证书有ca.crt、rnd185.fro.local.key、rnd185.fro.local.crt(mqtt服务器用到);mqtt18501.crt、mqtt18501.key(mqtt客户端用到,nginx代理wss也会用到)。

再次配置mosquitto.conf,如下:

port 1883

listener 8883
cafile /xx/xx/ca.crt
certfile /xx/xx/rnd185.fro.local.crt
keyfile /xx/xx/rnd185.fro.local.key

listener 3003
protocol websockets

listener 3004
protocol websockets
cafile /xx/xx/ca.crt
certfile /xx/xx/rnd185.fro.local.crt
keyfile /xx/xx/rnd185.fro.local.key

4.这时先保证ws通信正常。

ws和wss客户端都使用node的同一套代码(wss只需要修改下var host = 'wss://nginx地址:443/mqtt'),node使用的mqtt版本为2.18.8。

var mqtt = require('mqtt');
var fs = require('fs');

var clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)

var host = 'ws://192.168.0.185:3003'

var options = {
  keepalive: 60,
  clientId: clientId,
  protocolId: 'MQTT',
  protocolVersion: 4,
  clean: true,
  reconnectPeriod: 1000,
  connectTimeout: 30 * 1000,
  will: {
    topic: 'WillMsg',
    payload: 'Connection Closed abnormally..!',
    qos: 0,
    retain: false
  },
  username: 'demo',
  password: 'demo',
  rejectUnauthorized: false
}

var client = mqtt.connect(host, options)

client.on('error', function (err) {
  console.log(err)
  client.end()
})

client.on('connect', function () {
  console.log('client connected:' + clientId)
})

client.subscribe('topic', { qos: 0 })

client.publish('topic', 'wss secure connection demo...!', { qos: 0, retain: false })

client.on('message', function (topic, message, packet) {
  console.log('Received Message:= ' + message.toString() + '\nOn topic:= ' + topic)
})

client.on('close', function () {
  console.log(clientId + ' disconnected')
})

脚本执行结果:

mqtt之wss。_第3张图片

服务器日志:

mqtt之wss。_第4张图片

5.如果按照前面的配置,mqtts也是可以的,网上有很多资料,不再细说;这时wss的大坑就来了,在脚本中直接使用wss是有问题的。

测试步骤:

第1步:修改node脚本,var host = 'wss://192.168.0.185:3004';

第2步:直接运行该脚本,客户端会连不上,而服务器将报错,不知道具体原因,有大神知道的可回复我。

客户端连接不上:

mqtt之wss。_第5张图片

服务器报错:

mqtt之wss。_第6张图片

6.使用nginx代码解决wss问题,安装nginx-1.14.0(我的为windows版本,应该跟系统无关),配置nginx.conf。

	upstream mqttws  {
		server 192.168.0.185:3003;  #mqtt服务器地址
	}

    server {
        listen       443;
        server_name  localhost;
        ssl on;
        ssl_certificate      C:\\frotech\\scratch-desktop-bak\\nginx-1.14.0\\ssl\\mqtt18501.crt;
        ssl_certificate_key  C:\\frotech\\scratch-desktop-bak\\nginx-1.14.0\\ssl\\mqtt18501.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
		
        location /mqtt {
            proxy_pass http://mqttws; 
			proxy_set_header   Host             $host;
			proxy_set_header   X-Real-IP        $remote_addr;
			proxy_set_header   X-Forwarded-For  $remote_addr;
			
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }

7.启动nginx,到nginx安装路径下cmd执行start  nginx;修改node客户端脚本(var host = 'wss://192.6.1.74:443/mqtt',其它不用改,192.6.1.74为nginx主机地址,443为端口),运行node客户端脚本,这次可以连接上了。

客户端:

mqtt之wss。_第7张图片

服务器:

mqtt之wss。_第8张图片

你可能感兴趣的:(node,mqtt,mqtt,wss,mosquitto)