多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > 綜合技術(shù) > Linkit 7688 DUO(六) 加入MQTT物聯(lián)網(wǎng)協(xié)議

Linkit 7688 DUO(六) 加入MQTT物聯(lián)網(wǎng)協(xié)議

來源:程序員人生   發(fā)布時間:2016-06-08 08:37:31 閱讀次數(shù):6306次

Linkit 系列博文:

聯(lián)發(fā)科Linkit 7688 (1) 上手及在Mac下搭建OpenWrt交叉編譯環(huán)境,C語言編譯Hello,World

聯(lián)發(fā)科Linkit 7688 (2)GPIO基本操作與C語言編程

聯(lián)發(fā)科Linkit 7688 DUO(3): 通過 Arduino 控制外設(shè)和傳感器

Linkit 7688 DUO(4): 接上各種Arduino傳感器和模塊——基礎(chǔ)篇

Linkit 7688 DUO(5) 接上各種Arduino傳感器和模塊—擴(kuò)大篇

Linkit 7688 DUO(6) 加入MQTT物聯(lián)網(wǎng)協(xié)議


本篇介紹 將 MQTT物聯(lián)網(wǎng)協(xié)議加載到 Linkit 7688 DUO開發(fā)板上 ( 其中的源碼和方法也適用于所有的Linux系統(tǒng)、也合適于Windows系統(tǒng))

MQTT是IBM開發(fā)的1種物聯(lián)網(wǎng)即時通訊協(xié)議,該協(xié)議支持所有平臺,幾近可以把所有聯(lián)網(wǎng)物品、電腦APP、手機APP、網(wǎng)頁等連接起來,讓它們隨時相互交換信息。

有了MQTT協(xié)議,Linkit 7688開發(fā)板就能夠稱得上物聯(lián)網(wǎng)開發(fā)板了,可以實現(xiàn)很多場景,比如:手機遠(yuǎn)程控制、網(wǎng)頁遠(yuǎn)程控制、服務(wù)器監(jiān)測物體狀態(tài)等等。


1、MQTT協(xié)議簡介

1,MQTT是1種基于TCP的網(wǎng)絡(luò)消息協(xié)議,用于發(fā)送和接收消息。 

在1個MQTT網(wǎng)絡(luò)中,有1個服務(wù)器和多個客戶端。 每一個客戶端以TCP Socket與服務(wù)器連接,并保持為長連接。

客戶端可以是1個聯(lián)網(wǎng)物體、電腦軟件、手機APP、乃至是網(wǎng)頁。以下圖:



2,  消息傳輸采取發(fā)布/定閱(publish/subscribe)模式。

  客戶端可以發(fā)布(publish)消息, 每一個消息由1個主題(topic)和1個消息內(nèi)容組成。比如:某溫度傳感器發(fā)布1個消息: topic = "sensor1/temperature", message="25“

  客戶端可以定閱(subscribe)1個或多個主題的消息。 當(dāng)網(wǎng)絡(luò)中有人發(fā)布了這些主題的消息,則客戶端將收到這條消息。比如: 手機App定閱了 “sensor1/temperature"消息,則上述消息將被收到, 手機App就知道sensor1的溫度值了。

  由于客戶端與服務(wù)器保持著Socket長連接,消息將立即實時推送到客戶端,也就是說:PUSH到客戶端。

  MQTT服務(wù)器的主要作用是接收-轉(zhuǎn)發(fā):接收消息、判斷哪些客戶端定閱了該主題的消息,PUSH給相應(yīng)客戶端。

  這類機制,可以實現(xiàn)1對1發(fā)送消息,也能夠?qū)崿F(xiàn)1對多發(fā)送消息(群發(fā))。

利用場景舉例:

場景1:  手機APP發(fā)布查溫度的消息, 各個傳感器裝置收到消息后,發(fā)布溫度消息。則手機就能夠搜集到各個傳感器的溫度。

場景2:  當(dāng)火警傳感器裝置檢測到起火后,發(fā)布消息。 則定閱了該類型消息的手機、電腦等都可立即收到火警。


3,MQTT的消息包傳輸數(shù)據(jù)量很小(固定長度的頭部僅為 2 字節(jié)),能充分下降網(wǎng)絡(luò)流量,非常合適于低帶寬、不可靠連接、嵌入式裝備。 

同時非常合適于手機等移動通訊環(huán)境,可以省流量、省電。因此,有人用MQTT作為手機PUSH使用。


4, 為保障消息有效力到達(dá),MQTT定義了3種消息發(fā)布服務(wù)質(zhì)量(Qos, Quality Of Service):

“最多1次”(At most once),開消最小,消息發(fā)布完全依賴底層 TCP/IP 網(wǎng)絡(luò),會產(chǎn)生消息丟失或重復(fù)。這1級別可用于以下情況,環(huán)境傳感器數(shù)據(jù),丟失1次讀記錄無所謂,由于不久后還會有第2次發(fā)送。
“最少1次”(At least once),確保消息到達(dá),但消息重復(fù)可能會產(chǎn)生。
“只有1次”(Exactly once),確保消息到達(dá)1次。這1級別可用于以下情況,在計費系統(tǒng)中,消息重復(fù)或丟失會致使不正確的結(jié)果。經(jīng)常使用于精確控制。

每條消息都可以有自己的Qos定義。每個客戶端定閱某主題時,也能夠指定Qos.


5, MQTT協(xié)議由IBM公司于1999年提出,經(jīng)過量年發(fā)展已比較成熟,目前版本是3.1.1。服務(wù)器和客戶端均有多個開源實現(xiàn),支持各類操作系統(tǒng)和開發(fā)語言。


2、合適嵌入式裝備的MQTT協(xié)議客戶端(C語言實現(xiàn))

對Linkit 7688開發(fā)板,我選取 “Eclipse Paho C” 的MQTT 客戶端開源代碼庫 。其主頁在這:https://www.eclipse.org/paho/clients/c/

這個代碼庫是IBM公司提供的,Eclipse項目組保護(hù)的,可以稱為官方的。

我的使用方式是: 將它作為1個函數(shù)庫, 在Linkit 7688上編寫C語言程序,實現(xiàn)MQTT消息收發(fā)。

這個庫有1點點復(fù)雜,需要對協(xié)議比較了解。如果你要完全弄懂它,需要先讀它的文檔(http://www.eclipse.org/paho/files/mqttdoc/Cclient/index.html)

我們1般總是喜歡把復(fù)雜的事情簡單化,因此,我對這個庫進(jìn)行了封裝,  變成幾個函數(shù), 不需要懂太多就能夠用.

庫和例程在我的資源中下載:  MQTT客戶端Paho C代碼

解壓后,其中mqtt目錄是Paho C所有的庫文件( 原本的文件都沒改,我增加了 mqtt_client.c ,  mqtt_client.h 兩個文件),使用時將mqtt目錄復(fù)制到你的項目文件夾中便可。


在使用前,需要有1個測試用的MQTT服務(wù)器, 我用的是 IBM提供的測試服務(wù)器:  messagesight.demos.ibm.com, 端口是1883 (1883是MQTT的默許端口)

同時需要有1個測試用的MQTT客戶端作為對端,我用的是IBM提供的網(wǎng)頁版MQTT客戶端:http://m2m.demos.ibm.com/mqttclient/


1, 在Linkit 7688上編1個發(fā)送MQTT消息的程序:

  用Eclipse 建立1個交叉編譯項目 ( 開發(fā)環(huán)境搭建請見:聯(lián)發(fā)科Linkit 7688 (1) 上手及在Mac下搭建OpenWrt交叉編譯環(huán)境,C語言編譯Hello,World)

  將mqtt目錄復(fù)制到你的項目文件夾下。

  創(chuàng)建1個 mqtt_publish.c文件, 編寫主程序以下:

#include <stdio.h> #include <stdlib.h> #include <errno.h> #include "mqtt/mqtt_client.h"//這個是我對mqtt_client封裝后的頭文件 int publish(int argc, char ** argv) { mqtt_client *m; //mqtt_client 對象指針 int ret; //返回值 char *host = "messagesight.demos.ibm.com:1883";//測試服務(wù)器 char *topic = "test_topic"; //主題 char *client_id = "clientid33883";//客戶端ID; 對測試服務(wù)器,可以隨意寫 char *username = NULL;//用戶名,用于驗證身份。對測試服務(wù)器,無。 char *password = NULL;//密碼,用于驗證身份。對測試服務(wù)器,無。 int Qos; //Quality of Service //create new mqtt client object m = mqtt_new(host, MQTT_PORT, client_id); //創(chuàng)建對象,MQTT_PORT = 1883 if ( m == NULL ) { printf("mqtt client create failure, return code = %d\n", errno); return 1; } else { printf("mqtt client created\n"); } //connect to server ret = mqtt_connect(m, username, password); //連接服務(wù)器 if (ret != MQTT_SUCCESS ) { printf("mqtt client connect failure, return code = %d\n", ret); return 1; } else { printf("mqtt client connect\n"); } //publish message Qos = QOS_EXACTLY_ONCE; //Qos ret = mqtt_publish(m, topic, "hello from Linkit 7688", Qos);//發(fā)布消息 printf("mqtt client publish, return code = %d\n", ret); mqtt_disconnect(m); //disconnect mqtt_delete(m); //delete mqtt client object return 0; }


主程序分為3個步驟:

1, 調(diào)用 mqtt_new()創(chuàng)建 客戶端對象

2, 調(diào)用 mqtt_connect() 連接服務(wù)器

3, 調(diào)用 mqtt_publish() 發(fā)布消息


用Eclipse編譯項目

如果出現(xiàn)毛病提示:

undefined reference to `pthread_create’
undefined reference to `pthread_mutexattr_init’

這是由于沒有在編譯連接時包括pthread庫, 解決辦法: 需在GCC中添加 -lpthread 參數(shù)。

如果出現(xiàn)毛病提示:

undefined reference to `dlclose’
undefined reference to `dlopen’
undefined reference to `dlsym
這是由于沒有在編譯連接時包括dl庫, 解決辦法: 需在GCC中添加 -ldl 參數(shù)

在eclipse中的操作是:   項目Property =>  C/C++ Build => Settings, 在"Tools Setting"頁,選Cross GCC linker, 在 "Linker flags"編譯框中填入:  -lpthread -ldl

OK, 編譯成功了。


用scp將 mqtt_publish 程序上傳到 linkit 7688:   scp mqtt_publish root@mylinkit.local:/root


先準(zhǔn)備接收消息的網(wǎng)頁客戶端: 用閱讀器打開 http://m2m.demos.ibm.com/mqttclient/

在Connect欄中, 點Connect.

在Subscribe欄中,將topic設(shè)為 test_topic, 按subscribe

OK, 網(wǎng)頁客戶端準(zhǔn)備好接收主題(topic)為 test_topic的消息了。


用SSH登錄入Linkit 7688,  運行 mqtt_publish 程序。

運行結(jié)果, 顯示mqtt 創(chuàng)建、連接、發(fā)布消息的進(jìn)程, return code >=0 表示成功

mqtt client created

mqtt client connect

mqtt client publish,  return code = 1


這時候,可以看到閱讀器中的MQTT網(wǎng)頁客戶端收到了Linkit 7688發(fā)布的MQTT消息


 

成功了: Linkit 7688發(fā)布MQTT消息到服務(wù)器, 網(wǎng)頁客戶端實時收到服務(wù)器推送來的消息。



2, 在Linkit 7688上編1個接收MQTT消息的程序:

  用Eclipse 建立1個交叉編譯項目 ( 開發(fā)環(huán)境搭建請見:聯(lián)發(fā)科Linkit 7688 (1) 上手及在Mac下搭建OpenWrt交叉編譯環(huán)境,C語言編譯Hello,World)

  將mqtt目錄復(fù)制到你的項目文件夾下。

  創(chuàng)建1個 mqtt_subscribe.c文件, 編寫主程序以下:

#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include "mqtt/mqtt_client.h"//這個是我對mqtt_client封裝后的頭文件 int running = 1; void stop_running(int sig) { signal(SIGINT, NULL); running = 0; } int main(int argc, char ** argv) { mqtt_client *m; //mqtt_client 對象指針 int ret; //返回值 char *host = "messagesight.demos.ibm.com:1883";//測試服務(wù)器 char *topic = "test_topic"; //主題 char *client_id = "clientid33883";//客戶端ID; 對測試服務(wù)器,可以隨意寫 char *username = NULL;//用戶名,用于驗證身份。對測試服務(wù)器,無。 char *password = NULL;//密碼,用于驗證身份。對測試服務(wù)器,無。 int Qos; //Quality of Service //create new mqtt client object m = mqtt_new(host, MQTT_PORT, client_id); //創(chuàng)建對象,MQTT_PORT = 1883 if ( m == NULL ) { printf("mqtt client create failure, return code = %d\n", errno); return 1; } else { printf("mqtt client created\n"); } //connect to server ret = mqtt_connect(m, username, password); //連接服務(wù)器 if (ret != MQTT_SUCCESS ) { printf("mqtt client connect failure, return code = %d\n", ret); return 1; } else { printf("mqtt client connect\n"); } //subscribe Qos = QOS_EXACTLY_ONCE; ret = mqtt_subscribe(m, topic, Qos);//定閱消息 printf("mqtt client subscribe %s, return code = %d\n", topic, ret); signal(SIGINT, stop_running); signal(SIGTERM, stop_running); printf("wait for message of topic: %s ...\n", topic); //loop: waiting message, 循環(huán) while (running) { int timeout = 200; if ( mqtt_receive(m, timeout) == MQTT_SUCCESS ) { //recieve message,接收消息 printf("received Topic=%s, Message=%s\n", m->received_topic, m->received_message); } mqtt_sleep(200); //sleep a while } mqtt_disconnect(m); //disconnect printf("mqtt client disconnect"); mqtt_delete(m); //delete mqtt client object return 0; }

主程序分為幾個步驟:

1, 調(diào)用 mqtt_new()創(chuàng)建 客戶端對象

2, 調(diào)用 mqtt_connect() 連接服務(wù)器

3, 調(diào)用 mqtt_subscribe() 定閱消息

4, 進(jìn)入循環(huán):不斷用 mqtt_receive()檢測有否新消息,如有,則打印出來。

用Eclipse編譯項目 (記得必須在GCC中加入連接選項:  -lpthread -ldl )

OK, 編譯成功了。

用scp將 mqtt_subscribe 程序上傳到 linkit 7688:   scp mqtt_subscribe root@mylinkit.local:/root


用SSH登錄入Linkit 7688,  運行 mqtt_subscribe 程序。則此時出現(xiàn):

mqtt client created

mqtt client connect

mqtt client subscribe,  return code = 0

wait for message of topic: test_topic ...


顯示程序在等待消息到來


準(zhǔn)備發(fā)送消息的網(wǎng)頁客戶端: 用閱讀器打開 http://m2m.demos.ibm.com/mqttclient/

在Connect欄中, 點Connect.

在Publish欄中,將topic設(shè)為 test_topic, 將Message設(shè)為 “Say hello to linkit 7688” 按publish, 則發(fā)出1條MQTT消息。


這時候, 看Linkit 7688 SSH客戶端,可以看到,Linkit7688立即收到了這條MQTT消息

mqtt client created

mqtt client connect

mqtt client subscribe,  return code = 0

wait for message of topic: test_topic ...

received Topic=test_topic, Message=Say hello to linkit 7688


成功了: Linkit 7688 實時收到了網(wǎng)頁客戶端發(fā)來的消息。

mqtt_subscribe 程序是死循環(huán),1直在接收消息。 可按CTRL+C退出。



通用性: Eclipse Paho C 的 MQTT客戶端代碼,可以運行在Linux、Windows、Mac上。所以,上述的代碼可以用于Linux、Windows、Mac操作系統(tǒng),編寫各種App。

對Android手機, Eclipse Paho另提供了Java的代碼庫。





生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 国产五月天在线 | 国产成人免费视频精品一区二区 | 自拍自偷| 性色va| 嫩草影院在线观看精品 | 欧美三级午夜理伦三级小说 | 午夜三级在线观看 | 亚洲人成伊人成综合网久久久 | 久久久久久一品道精品免费看 | 亚洲高清国产一区二区三区 | 欧美区一区二区三 | 波多野结衣不卡 | 欧美性大战久久久久久久 | 日本xxwwwxxxx| 国产亚洲欧美日本一二三本道 | 国产成人毛片 | 国产性tv国产精品 | 一区二区三区欧美日韩国产 | 免费网站www网站免费 | 亚洲国产天堂久久九九九 | 波多野一区 | 欧美国产精品一区二区免费 | 精品视频在线观看免费 | 国产区精品视频 | 久久99精品久久久久久秒播 | 久久不卡精品 | 亚洲欧美日韩综合在线一区二区三区 | 午夜精品国产爱在线观看不卡 | 中文字幕欧美日韩高清 | 国产农村妇女毛片精品久久 | av蜜桃| 午夜在线播放视频在线观看视频 | 国内自拍 亚洲系列 欧美系列 | 欧美特黄一片aa大片免费看 | 欧美精品在线免费 | 福利片福利一区二区三区 | 国内小情侣一二三区在线视频 | 欧美国产亚洲精品a第一页 欧美国产亚洲精品高清不卡 | 秋霞一级在线理论片欧美 | 国产精品亚洲综合第一区 | 欧美猛交 |