paho實現MQTTClient釋出訊息

難賦深情發表於2020-10-25

paho實現MQTTClient釋出訊息

接下來會用paho開源的一個專案,實現mqtt客戶端釋出訊息,此文主要參考MQTT Client library for C,Paho給出的建立一個客戶端有如下類似的步驟:

1、安裝

//從github上下載專案
git clone https://github.com/eclipse/paho.mqtt.c.git
//進入資料夾
cd paho.mqtt.c
//編譯
make

2、目錄介紹

在這裡插入圖片描述

src:原始檔、庫檔案目錄
build:編譯過後的動態庫及執行檔案
2.1、src目錄

src中有許多原始檔,有釋出、訂閱、同步、非同步檔案。
在這裡插入圖片描述

2.2、build目錄

build檔案是編譯過後的執行檔案,也是同步、非同步、釋出、訂閱訊息等功能
在這裡插入圖片描述

3、實現過程

  1.建立一個客戶端物件;
  2.設定連線MQTT伺服器的選項;
  3.如果多執行緒(非同步模式)操作被使用則設定回撥函式(詳見 Asynchronous >vs synchronous client applications);
  4.訂閱客戶端需要接收的任意話題;
  5.重複以下操作直到結束:
    a.釋出客戶端需要的任意資訊;
    b.處理所有接收到的資訊;
  6.斷開客戶端連線;
  7.釋放客戶端使用的所有記憶體。

4、檔案操作

我們直接使用paho自帶檔案,首先修改src中MQTTClient_publish.c原始碼。

4.1、修改資訊
//mqtt伺服器地址
#define ADDRESS “tcp://m2m.eclipse.org:1883”
//客戶端號
#define CLIENTID “ExampleClientPub”
//主題
#define TOPIC “MQTT Examples”
//訊息
#define PAYLOAD “Hello World!”
4.2、新增資訊

需要新增伺服器中使用者名稱和密碼

 char *username= "test"; //新增的使用者名稱
 char *password = "test"; //新增的密碼

將其寫入客戶端選項

 conn_opts.username = username; //將使用者名稱寫入連線選項中
 conn_opts.password = password; //將密碼寫入連線選項中

5、原始碼

原始碼我做了詳盡的解釋,其中有許多函式需要自己去上面檔案自己檢視,下面這是同步釋出,不是非同步,非同步的程式碼也有,大家可以去看上面的網站

/*******************************************************************************
 * Copyright (c) 2012, 2020 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * and Eclipse Distribution License v1.0 which accompany this distribution. 
 *
 * The Eclipse Public License is available at 
 *   https://www.eclipse.org/legal/epl-2.0/
 * and the Eclipse Distribution License is available at 
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Ian Craggs - initial contribution
 *******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"

#define ADDRESS     "59.110.42.24:1883"
#define CLIENTID    "0bd981c5-a055-4196-8b7f-efb9f7a4d6ac"
#define TOPIC       "test"
#define PAYLOAD     "Hello World!"
#define QOS         1
#define TIMEOUT     10000L

int main(int argc, char* argv[])
{
    //宣告mqtt客戶端
    MQTTClient client;
    //初始化客戶端選項 conn_opts
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    //訊息初始化 pubmsg
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;
    int rc;
    char *username = "test";
    char *password = "test";
    if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID,
        MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS)
    {
         printf("Failed to create client, return code %d\n", rc);
         exit(EXIT_FAILURE);
    }
    //保持心跳20
    conn_opts.keepAliveInterval = 20;
    //清理會話
    conn_opts.cleansession = 1;
    //客戶端的使用者名稱和密碼
    conn_opts.username = username;
    conn_opts.password = password;
    //建立連線
    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
    //訊息負載(內容)
    pubmsg.payload = PAYLOAD;
    //訊息長度
    pubmsg.payloadlen = (int)strlen(PAYLOAD);
    //訊息質量分為0:不重要的訊息比如溫度,可以多次上傳丟失一次沒事。1:可能會丟失1次 2:永遠不會丟失
    pubmsg.qos = QOS;
    //有true和false 判斷訊息是否保留
    pubmsg.retained = 0;
    //釋出訊息 token是訊息釋出後,傳遞令牌將返回客戶端檢查令牌是否已成功傳遞到其目的地
    if ((rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS)
    {
         printf("Failed to publish message, return code %d\n", rc);
         exit(EXIT_FAILURE);
    }

    printf("Waiting for up to %d seconds for publication of %s\n"
            "on topic %s for client with ClientID: %s\n",
            (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
    //阻塞函式,等待訊息釋出
    rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
    printf("Message with delivery token %d delivered\n", token);

    if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS)
    	printf("Failed to disconnect, return code %d\n", rc);
    //斷開連線
    MQTTClient_destroy(&client);
    return rc;
}

6、實現效果

伺服器中釋出
在這裡插入圖片描述
mqtt測試軟體訂閱的訊息就能接受到
在這裡插入圖片描述

相關文章