nginx配置支持wss,https网页连接mqtt

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010277446/article/details/88059670

之前在前端网页上写一个小网站,用于开发时在线订阅、发送mqtt数据包。
当部署在线上服务器时,因为域名网页有加载Https证书,所以连接mqtt时只能选用wss方式,却没有成功连接上mqtt。而mqtt的ws连接方式是可以的。

一、服务端配置

1.mqtt的配置文件

先来看线上服务器中mqtt配置文件

port 1883

listener 61613
protocol websockets

配置中,1883是tcp连接, 61613是ws连接方式

2.nginx配置方案

采用的方案是,在nginx中配置wss支持,再反向代理转至mqtt的ws连接端口,实测这样配置后mqtt是可以在https网页中通过wss正常连接、收发数据等。

# 先定义一个upstream分发到ws,此处反向代理或做负载均衡
upstream mqttServer {
    server localhost:61613;
}
# 配置wss支持
location /mqttwss {
	proxy_set_header Host $http_host;
	proxy_pass http://mqttServer;
    proxy_http_version 1.1;
	proxy_set_header X-Client-IP $remote_addr;
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
	proxy_read_timeout 300s; # 默认是60秒,可设置
}

二、前端wss连接

选择 Eclipse Paho JavaScript Client 连接库
utility.js

/*
Eclipse Paho MQTT-JS Utility
This utility can be used to test the Eclipse Paho MQTT Javascript client.
*/

// Create a client instance
client = null;
connected = false;

// called when the client connects
function onConnect(context) {
  // Once a connection has been made, make a subscription and send a message.
  alert("连接成功: \nHost: " + context.invocationContext.host + ':' + context.invocationContext.port + context.invocationContext.path + ' \nClientID: ' + context.invocationContext.clientId);
  connected = true;
}

function onFail(context) {
  alert("连接失败: " + context.errorMessage);
  connected = false;
}

// called when the client loses its connection
function onConnectionLost(responseObject) {
  if (responseObject.errorCode !== 0) {
    alert("连接已断开,请重新连接: " + responseObject.errorMessage);
  }
  connected = false;
}

// called when a message arrives
/*called when a message arrives
* @message: 收到消息
*/
function onMessageArrived(message) {
  alert('Message Recieved: \nTopic: '+message.destinationName+'\nPayload: '+message.payloadString+'\nQoS: '+message.qos);
  // alert(message);
  var messageTime = new Date().toISOString();
  // pare message
  // alert('Topic:' + message.destinationName);
  // alert('Payload:' + safe_tags_regex(message.payloadString));
  // alert('messageTime:' + messageTime);
  // alert('QoS:' + message.qos);
}

/*连接*/
function connect(clientId){
    var hostname = 'mqtt.example.cn';
    var port = 61613;
    // var clientId = 'msg_publisher_1';

    var path = '/mqttwss';
    var user = 'username';
    var pass = 'password';
    var keepAlive = 90;
    var timeout = 3;
    var tls = true;
    var cleanSession = false;
    var lastWillTopic = '/test/will/' + clientId;
    var lastWillQos = 1;
    var lastWillRetain = false;
    var lastWillMessage = 'net offline';


    if(path.length > 0){
      client = new Paho.MQTT.Client(hostname, port, path, clientId);
    } else {
      client = new Paho.MQTT.Client(hostname, port, clientId);
    }

    // set callback handlers
    client.onConnectionLost = onConnectionLost;
    client.onMessageArrived = onMessageArrived;


    var options = {
      invocationContext: {host : hostname, port: port, path: client.path, clientId: clientId},
      timeout: timeout,
      keepAliveInterval:keepAlive,
      cleanSession: cleanSession,
      useSSL: tls,
      onSuccess: onConnect,
      onFailure: onFail
    };



    if(user.length > 0){
      options.userName = user;
    }

    if(pass.length > 0){
      options.password = pass;
    }

    if(lastWillTopic.length > 0){
      var lastWillMessage = new Paho.MQTT.Message(lastWillMessage);
      lastWillMessage.destinationName = lastWillTopic;
      lastWillMessage.qos = lastWillQos;
      lastWillMessage.retained = lastWillRetain;
      options.willMessage = lastWillMessage;
    }

    // connect the client
    client.connect(options);
}

/*连接断开*/
function disconnect(){
    client.disconnect();
    alert('Connection - Disconnected.');
    connected = false;
}

/*发送mqtt消息包
* @topic: 订阅主题 string
* @qos: 消息质量 int
* @message: 消息体
* @retain: 是否保留 bool
*/
function publish(topic, qos, message, retain){
    if (!connected) {
        alert('mqtt未连接,请稍后再试');
        return;
    }
    alert('Publishing Message: \nTopic: '+topic+'\nQoS: ' + qos + '\nMessage: '+message);
    message = new Paho.MQTT.Message(message);
    message.destinationName = topic;
    message.qos = qos;
    message.retained = retain;
    client.send(message);
}

/*订阅主题
* @topic: 订阅主题 string
* @qos: 消息质量 int
*/
function subscribe(topic, qos){
    if (!connected) {
        alert('mqtt未连接,请稍后再试');
        return;
    }
    alert('Subscribing to: \nTopic: ' + topic +'\nQoS: '+qos);
    client.subscribe(topic, {qos: qos});
}
/*取消主题订阅
* @topic: 订阅主题 string
* @qos: 消息质量 int
*/
function unsubscribe(topic){
    client.unsubscribe(topic, {
         onSuccess: unsubscribeSuccess,
         onFailure: unsubscribeFailure,
         invocationContext: {topic : topic}
     });
}
function unsubscribeSuccess(context){
    alert('Successfully unsubscribed from ', context.invocationContext.topic);
}
function unsubscribeFailure(context){
    alert('Failed to  unsubscribe from ', context.invocationContext.topic);
}


// Just in case someone sends html
function safe_tags_regex(str) {
   return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

function makeid()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

猜你喜欢

转载自blog.csdn.net/u010277446/article/details/88059670
今日推荐