1. 程式人生 > 其它 >阿里雲Mqtt連線報錯解決

阿里雲Mqtt連線報錯解決

技術標籤:物聯網物聯網arduino阿里雲

關於The Client identifier is correct UTF-8 but not allowed by the Server連線報錯解決

錯誤原因

如果是使用阿里雲平臺進行mqtt的裝置連線,那麼在匯入PubSubClient庫的時候進行裝置mqtt連線的時候可能會出現如下的錯誤:
The Client identifier is correct UTF-8 but not allowed by the Server
因為在庫裡面預設的mqtt包和keepalive,以及超時的時間都比較小,很可能會還沒連上就報錯了。

阿里雲物聯網平臺要求 CONNECT指令中需包含Keep Alive(保活時間)。保活心跳時間取值範圍為30至1200秒。如果心跳時間不在此區間內,物聯網平臺會拒絕連線。建議取值300秒以上。如果網路不穩定,將心跳時間設定高一些。

解決方法:

進入目錄: C:\Users\admin\Documents\Arduino\libraries\PubSubClient\src
找到下面的.h檔案對其進行引數修改
在這裡插入圖片描述
可修改引數如下:

// MQTT_VERSION : Pick the version
//#define MQTT_VERSION MQTT_VERSION_3_1
#ifndef MQTT_VERSION
#define MQTT_VERSION MQTT_VERSION_3_1_1
#endif
 
// MQTT_MAX_PACKET_SIZE : Maximum packet size
#ifndef MQTT_MAX_PACKET_SIZE
#define MQTT_MAX_PACKET_SIZE 1024 #endif // MQTT_KEEPALIVE : keepAlive interval in Seconds #ifndef MQTT_KEEPALIVE #define MQTT_KEEPALIVE 300 #endif // MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds #ifndef MQTT_SOCKET_TIMEOUT #define MQTT_SOCKET_TIMEOUT 60 #endif

(附)阿里雲裝置連線

下面是可以通過修改三元組資訊進行伺服器連線的程式碼,可以直接通過Arduino進行燒錄,僅做程式碼參考,具體連線教程可以看菜鳥哥的部落格進行同步學習:

https://blog.csdn.net/dpjcn1990/article/details/104561464

#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

const char* WIFI_SSID     = "WiFi賬號"; // WiFi賬號
const char* WIFI_PASSWORD = "WiFi密碼"; // WiFi密碼

/******************產品/裝置配置(每個人需要根據自己的產品裝置資訊去動態更換)**********************/
#define PRODUCT_KEY "產品key"  //產品key  從產品詳情獲取
#define DEVICE_NAME "裝置deviceName "  //裝置deviceName  從裝置詳情獲取
// 服務端相關
#define MQTT_SERVER   PRODUCT_KEY ".iot-as-mqtt.cn-shanghai.aliyuncs.com" //阿里雲MQTT服務地址
#define MQTT_PORT     1883                                               //MQTT服務埠
// 校驗三元組
#define MQTT_CLIENT_ID  DEVICE_NAME "|securemode=3,signmethod=hmacsha1|" //mqtt clientid
#define MQTT_USERNAME   DEVICE_NAME "&" PRODUCT_KEY                      //mqtt username
#define MQTT_PASSWORD   "password"       //mqtt password 通過生成工具獲得
// 相關主題 自定義一個主題
#define TOPIC1 "/" PRODUCT_KEY "/" DEVICE_NAME "/user/setledstatus"
/*************************************************************************************************/

void mqtt_callback (char* topic, byte* payload, unsigned int length);
void doWiFiTick();
void connect_wifi();
void connectToMqtt();
const __FlashStringHelper* connectErrorToString(int8_t code);

WiFiClient client;
PubSubClient mqttclient(MQTT_SERVER, MQTT_PORT, &mqtt_callback, client);

bool ICACHE_FLASH_ATTR connectHTTPS() {
  Serial.print("connecting to ");
  Serial.println(MQTT_SERVER);
  if (!client.connect(MQTT_SERVER, MQTT_PORT)) {
    Serial.println(F("connection failed"));
    return false;
  }
  else {
    Serial.println(F("connection succeed"));
    return true;
  }
}

void setup() {
  // put your setup code here, to run once:
  delay(2000);
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("");
}

void loop() {
  // put your main code here, to run repeatedly:
  ESP.wdtFeed();
  doWiFiTick();
  if (WiFi.status() == WL_CONNECTED) {
    connectToMqtt();
    mqttclient.loop();
  }
  delay(2000);
}

/**
 * 功能:連線到WiFi熱點
 */
void connect_wifi() {
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

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

  Serial.print(F("\nWiFi connected to "));
  Serial.println(WIFI_SSID);
  Serial.print(F("IP address: "));
  Serial.println(WiFi.localIP());
}

/**
 * 功能:連線到Mqtt
 */
void connectToMqtt() {
  if (mqttclient.connected()) {
   return;
  }

  Serial.print(F("Connecting to MQTT... "));

  int8_t ret;
  uint8_t retries = 3;

  while (!mqttclient.connect(MQTT_CLIENT_ID, MQTT_USERNAME,MQTT_PASSWORD)) { // connect will return true for connected
      Serial.println(connectErrorToString(mqttclient.state()));
      Serial.println(F("Retrying MQTT connection in 5 seconds..."));
      mqttclient.disconnect();
      delay(5000);  // wait 5 seconds
      retries--;
      if (retries == 0) {
        // basically die and wait for WDT to reset me
        while (1);
      }
      yield();
  }
  Serial.println(F("Success!"));
  // 訂閱主題
  mqttclient.subscribe(TOPIC1);

}

/**
 * 功能:連線路由心跳函式
 */
void doWiFiTick() {
  static bool taskStarted = false;
  static bool startSTAFlag = false;
  static uint32_t lastWiFiCheckTick = 0;

  if (!startSTAFlag) {
    startSTAFlag = true;

    Serial.print("connect to ap:");
    Serial.println(WIFI_SSID);
    WiFi.disconnect();
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.printf("Heap size:%d\r\n", ESP.getFreeHeap());
  }

  //未連線1s重連
  if ( WiFi.status() != WL_CONNECTED ) {
    if (millis() - lastWiFiCheckTick > 1000) {
      lastWiFiCheckTick = millis();
      Serial.print(".");
    }
  }
  //連線成功建立
  else {
    if (taskStarted == false) {
      taskStarted = true;
      Serial.print("\r\nGet IP Address: ");
      Serial.println(WiFi.localIP());
    }
  }
}

/**
 * 功能:MQTT回撥
 * 引數:
 *   1. topic   主題
 *   2. payload 載體
 *   3. length  載體長度
 */
void mqtt_callback (char* topic, byte* payload, unsigned int length) {
  byte *end = payload + length;
  for (byte *p = payload; p < end; ++p) {
    Serial.print(*((const char *)p));
  }
  Serial.println("");
  parseMqttResponse((char *)payload);
}

/**
 * 解析mqtt資料
 */
void parseMqttResponse(char* payload){
   Serial.println("start parseOneNetMqttResponse");
   StaticJsonBuffer<100> jsonBuffer;
     // StaticJsonBuffer 在棧區分配記憶體   它也可以被 DynamicJsonBuffer(記憶體在堆區分配) 代替
     // DynamicJsonBuffer  jsonBuffer;
   JsonObject& root = jsonBuffer.parseObject(payload);

     // Test if parsing succeeds.
   if (!root.success()) {
       Serial.println("parseObject() failed");
       return ;
   }

   String deviceName = root["dn"];
   int status = root["s"];

   if(strcmp(DEVICE_NAME,deviceName.c_str())== 0){
        if (status == 1) {
            digitalWrite(LED_BUILTIN, LOW);
        } else {
            digitalWrite(LED_BUILTIN, HIGH);
        }
    }
}

/**
 * 功能:列印錯誤
 * 引數:
 *   1. code   錯誤碼
 */
const __FlashStringHelper* connectErrorToString(int8_t code) {
   switch (code) {
      case 1: return F("The Server does not support the level of the MQTT protocol requested");
      case 2: return F("The Client identifier is correct UTF-8 but not allowed by the Server");
      case 3: return F("The MQTT service is unavailable");
      case 4: return F("The data in the user name or password is malformed");
      case 5: return F("Not authorized to connect");
      case 6: return F("Exceeded reconnect rate limit. Please try again later.");
      case 7: return F("You have been banned from connecting. Please contact the MQTT server administrator for more details.");
      case -1: return F("Connection failed");
      case -2: return F("Failed to subscribe");
      case -3: return F("Connection Lost");
      case -4: return F("Connection Timeout");
      default: return F("Unknown error");
   }
}