使用MQTT完成设备到微信小程序和网页端的数据通信

写在前面

记录一下自己做的项目。简单来讲:该项目使用esp8266向Apollo服务器发送消息,Apollo向微信小程序和网页端推送该消息。网页和小程序这两个客户端的代码都是用JS写的,都用到了paho-mqtt.js这个库。

Apollo服务器的搭建

关于Apollo服务器的搭建方法,看这篇博客搭建MQTT服务器及测试.可以说是非常详细了。

ESP12-E

编程使用的ArduinoIDE,引用了PubSubClient.h
也只是对“实例”=>“PubSubClient”=>“mqtt_esp8266”这个实例文件进行了简单修改。程序不复杂,就基本上没写注释。
主要的变化有两点:

  1. 服务器需要账号密码登陆,所以调用API时参数需要多填几个参数
  2. 关于发布消息长期保留的问题,在我之前记录的博客里有提到关于Apollo服务器保留消息
#include 
#include 

const char* ssid = "Medi";//wifi账号
const char* password = "88888889";
const char* mqtt_server = "";//服务器IP地址或域名
const int mqtt_port = 61613;
const char* mqttUserName = "admin";
const char* mqttPassword = "password";
const char* clientId = "ESP1";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
char msg1[50];
int value = 0;

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server,mqtt_port);
  client.setCallback(callback);
}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(clientId,mqttUserName,mqttPassword)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopichezhou", "begin",true);
      client.publish("lat-lon", "3119.04380,12123.36514",true);
      // ... and resubscribe
      client.subscribe("lon");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "hezhou #%ld", value);
    snprintf (msg1, 75, "1234567890");
    //Serial.print("Publish message: ");
    //Serial.println(msg);
    //client.publish("outTopichezhou", msg);
    //client.publish("outTopichezhou1", msg1);
    
  }
}

网页部分

我在服务器上搭建了IIS,发布网站,作为一个网页监管系统。
负责通信的部分如下

<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
<script> 
client = new Paho.MQTT.Client("IP或域名", Number(61623),'clientId');  
client.connect({userName:"admin",password:"password",onSuccess: onConnect});   
function onConnect() {  
    console.log("onConnected"); 
    client.subscribe("XXX");
} 
  client.onConnectionLost = onConnectionLost;//注册连接断开处理事件
        client.onMessageArrived = onMessageArrived;//注册消息接收处理事件
        function onConnectionLost(responseObject) {
            if (responseObject.errorCode !== 0) {
                console.log("onConnectionLost:"+responseObject.errorMessage);
                console.log("连接已断开");
             }
        }
        function onMessageArrived(message) {
		  console.log("话题:"+message.destinationName);
		  console.log("收到消息:"+message.payloadString);
		}
        //发送消息
        message = new Paho.MQTT.Message("hello");
		message.destinationName = "/topic";
		client.send(message);
</script>

WeApp

准备工作
小程序的js库还是应用上述的paho-mqtt.js,只是需做些许修改,使其能在小程序内应用。怎么修改的我不清楚,是某个博主开源的,但我找不到他了,源码下载paho_mqtt.zip。这个是老版本了,能用但是已经停止维护了。推荐一个github上的支持MQTT5的小程序demo:miniprogram-mqtt5
反向代理
因为微信的安全访问要求,wss默认端口号443,但是Apollo的wss端口为61624,所以用nginx做了反向代理。安装教程不写了,网上很多。安装好后,对nginx.conf做出修改(建议备份原件)。
注:如果只是为了学习、调试等,可以在小程序勾选“不校验合法域名”,就可以不做反向代理,甚至不用域名。

	server {
    		listen 443;
    		server_name www.XXX.cn; #填写绑定证书的域名
    
    		ssl on;
   		    ssl_certificate certs/对应文件名.crt;#证书放到conf文件夹内,此处填写相对地址
   	    	ssl_certificate_key certs/对应文件名.key;
    		ssl_session_timeout 5s;
    		ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
    		ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;    
	     	ssl_prefer_server_ciphers on;

    		location / {
       	 	    root   html; #站点目录
        		index  index.html index.htm;
    		}

    		location = /mqtt {
        		proxy_pass http://www.XXX.cn:61623;#你要代理的域名加端口号
        		proxy_redirect off;
        		proxy_set_header Host www.XXX.cn:61623;

        		proxy_set_header Sec-WebSocket-Protocol mqtt;
        	#	more_clear_headers Sec-WebSocket-Protocol;

       		    proxy_http_version 1.1;
        		proxy_set_header Upgrade $http_upgrade;
        		proxy_set_header Connection "upgrade";
        		}
	}

代码如下

const { Client, Message } = require('../../utils/paho-mqtt.js');
Page({
  onLoad:function(){
    var client = new Client("wss://你的域名/mqtt",'clientId随便填');//创建连接
	client.connect({ userName: "admin", password: "password", onSuccess: onConnect, useSSL: true });
	function onConnect() {
	  console.log("onConnected");
	  //订阅所有需要的话题
	  client.subscribe("lat-lon");
	}
	client.onMessageArrived = onMessageArrived;//注册消息接收处理事件
	function onMessageArrived(message) {
	  console.log(message.topic + ':' + message.payloadString);
	}
  }
}

你可能感兴趣的:(服务器,医疗箱)