【樹梅派3】安裝及測試 MQTT Server – mosquitto

1.安裝 mosquitto 伺服器

// 切換為管理者
sudo su

// 下載 mosquitto 認證 KEY
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key

// 加入至 APT 伺服器中
apt-key add mosquitto-repo.gpg.key

// 加入清單列表
cd /etc/apt/sources.list.d/
wget http://repo.mosquitto.org/debian/mosquitto-jessie.list

// 更新 APT 伺服器,使其連結 mosquitto
apt-get update
apt-cache search mosquitto

// 安裝
apt-get install mosquitto  mosquitto-clients

2.測試 MQTT

// 假設:
// Topic 名稱為 myTopic
// MQTT 伺服器所在 IP 為 192.168.0.201

// 在電腦一執行:訂閱 myTopic 資料
mosquitto_sub -h 192.168.0.201 -t myTopic

// 在電腦二執行:發布訊息至 myTopic
mosquitto_pub -h 192.168.0.201 -t myTopic -m "testMsg"

// 此時在電腦一畫面便可發現 testMsg 訊息

MQTT01

Ameba 測試程式碼:

#include <WiFi.h>
#include <PubSubClient.h>

// AP 基地台資訊設定
char ssid[] = "your network SSID";
char pass[] = "your network password";
int status  = WL_IDLE_STATUS;    // the Wifi radio's status

// MQTT 伺服器網路位址、ID、輸出Topic、輸出訊息、輸入Topic設定
char mqttServer[]     = "192.168.0.201";
char clientId[]       = "amebaClient";
char publishTopic[]   = "outTopic";
char publishPayload[] = "hello world";
char subscribeTopic[] = "inTopic";

// 發生傳入訊息時,將會傳回的函式
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();
}

WiFiClient wifiClient;
PubSubClient client(wifiClient);

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(clientId)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      Serial.print("publish:");
      Serial.println(publishTopic);
      Serial.println(publishPayload);
      client.publish(publishTopic, publishPayload);
      // ... and resubscribe
      client.subscribe(subscribeTopic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup()
{
  Serial.begin(38400);

  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  client.setServer(mqttServer, 1883);
  client.setCallback(callback);

  // Allow the hardware to sort itself out
  delay(1500);
}

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

注意問題:

1.MQTT 預設通訊埠為 1883,防火牆可能會阻擋。
2.Ameba 的發佈功能仍有問題。
3.如果發現 1883 被占用,可以使用 pkill mosquito 指令,將當在記憶體內部的 MQTT 強迫關閉。
可以用以下指令,查看系統中是否有應用程式在使用1883埠
ps -ef | grep mosq && netstat -tln | grep 1883

參考網址:

Mosquitto Debian repository
Installing MQTT Broker(Mosquitto) on Raspberry Pi
MQTT学习笔记——树莓派MQTT客户端 使用Mosquitto和paho-python
Ameba Arduino: 使用MQTT上傳與傾聽資料