2016年3月13日 星期日

Raspberry Pi安裝MQTT之應用 -- Android訊息推播

來源 http://cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pimqtt-android.html

Raspberry Pi安裝MQTT之應用 -- Android訊息推播

Android 常見的推播方式有GCM(Google Cloud Messaging)、XMPP、HTTP輪循方式(Web Service)以及本文所談的MQTT協定。
這四種推播的平台比較下各有優缺點,例如
GCM是Google的服務其優點簡單、無須安裝部屬。缺點則是受Google限制(上限 4kb 的輕量資料)。
XMPP優點是協定成熟、強大、可擴展性強、主要應用於聊天系統中。缺點則是協定較複雜、四種方式比較起來由於基於XML所以流量較大,需要軟硬體部署。
Web Service則是定時透過HTTP服務獲取最新訊息。優點是實現簡單、可控性強,部署硬體成本較低。缺點則是無法做到即時性的廣播。
MQTT優點協議簡潔、小巧、可擴展性強、節省頻寬。缺點不夠成熟、實現較複雜、需要軟硬體部署。

另外,下圖是MQTT與其他比較知名的大型原廠推播系統的比較,參考一下!

MQTT並不是一個新的技術,早在1999年由IBM的Andy Stanford-Clark及 Arcom (現為Eurotech)的Arlen Nipper這位所一起創造MQTT這個協定。只是這一陣子物聯網(IoT)又被炒作的變成一種熱門技術前提下,MQTT是一種很適合應用在物聯網上的一項技術,因此本篇就在樹梅派上採用MQTT協定來做Android訊息推播的平台。

MQTT是一個 machine-to-machine (M2M) 的發佈(Publish)/訂閱(Subscribe)訊息的傳輸協定,簡單來說當發佈者將訊息送至Topic平台,而Topic會將這個訊息送到所註冊的訂閱者。
一般來說發佈者可以是一個Sensors也可以是一個推播訊息的入口。訂閱者可以是個伺服器上的應用服務也可以是個手機。
其關係如下圖所示:
MQTT設計構想是採開放、簡單、輕量、易於實現同時支援離線訊息及訊息保留的功能。適用於受限制的環境,例如小頻寬、不穩定的網路或是資源有限的嵌入設備。其協定的特點如下:
1.使用發佈(Publish)/訂閱(Subscribe)訊息模式,提供一對多的訊息發佈。
2.使用 TCP/IP 提供網路連接。
3.具有多重QOS訊息傳輸,有三種用於訊息傳遞的服務品質::
4.使用網路頻寬小(2 bytes at minimum),減少通訊協定交換量。
5.使用 Last Will 和 Testament (最後留言)特性,可通知訂閱者用戶端與 MQTT 伺服器的連線異常中斷。

詳細資料請參考MQTT V3.1 Protocol Specification 說明

由上述的關係圖中,我們明白發佈者與訂閱者的中間需要一個平台,而這個平台最簡單的方式就是採用MQTT Broker
常見的MQTT Broker大致有Apache Apollo、HiveMQ、Mosca、Mosquitto、RabbitMQ、RSMB、...其比較如下表所示:
本篇文章的MQTT Broker則是採用Mosquitto,Mosquitto是一個實現了MQTT3.1協議的開源(BSD許可證)代理服務器,由MQTT協議創始人之一的Andy Stanford-Clark開發,它為我們提供了輕量級數據交換的解決方案。其官網為:http://mosquitto.org/,至目前為止他的最新版本為1.4。
實作:
環境說明:
Raspberry Pi
EDIMAX 訊舟 EW-7822Uan 300M USB無線網路
SanDisk 16G microSDHC card

作業系統:
RASPBIAN (NOOBS 1.4.0 2015-02-18 )
mosquitto 1.4

步驟:
安裝的方式大致上有兩種,一種是下載原始碼來進行編譯,這種方式可以用到最新版的軟體;另一種則是採用apt-get方式,這種方式比較簡單本文則採取這種方式來安裝。

1.安裝相關套件及含式庫:
sudo apt-get install libssl-dev libwrap0-dev libc-ares-dev uuid-dev

2.安裝Mosquitto
a.採用下載原始碼來進行編譯

wget http://mosquitto.org/files/source/mosquitto-1.4.tar.gz
tar zxvf mosquitto-1.4.tar.gz
cd mosquitto-1.4/
make all
sudo make install
sudo ldconfig

b.採用apt-get方式 (本文所採用方式)
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
rm mosquitto-repo.gpg.key

cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-repo.list
sudo apt-get update

sudo apt-get install mosquitto mosquitto-clients

按照上述步驟即完成Mosquitto軟體安裝。接著驗證一下Mosquitto是否可以正確執行。
3.首先開啟兩個視窗,或者使用兩個ssh連線。

4.在第一個視窗中執行:(當作訂閱者角色)
mosquitto_sub -d -t hello/world
5.在另一個視窗執行:(當作發佈者角色)
mosquitto_pub -d -t hello/world -m "Hi, This test message."
6.然後此時回到第一個視窗你可以看到剛剛傳送的訊息。
7.此時,在第二個視窗中執行下列指令,可以看到Mosquitto的一些資訊這表示Mosquitto服務是正在執行中,由此我們可以知道Mosquitto的參數檔案是/etc/mosquitto/mosquitto.conf;所使用的網路埠號是1883。
ps -ef | grep mosq && netstat -tln | grep 1883
執行下列指令可以關閉Mosquitto服務:
sudo /etc/init.d/mosquitto stop

執行下列指令可以開啟Mosquitto服務:
sudo /etc/init.d/mosquitto start

查看MQTT訂閱者執行情況:
mosquitto_sub -v -t \$SYS/#

安裝至此,已經完成安裝項目。
接著,已經安裝好Mosquitto這個MQTT Broker,接下來介紹一下MQTT的工具。

WMQTT Utility (ia92)
ia92是IBM為了它們家的WebSphere所開發的一套工具,可以到官網下載ia92.zip
下載後解壓縮,可以在J2SE目錄下找到一個wmqttSample.jar檔案,直接用java執行即可。
java -jar wmqttSample.jar

由上圖執行畫面所示,畫面分為三個區塊:
最上面是連線區塊
中間是訂閱者(Subscribe)區塊
下面是發佈者(Publish)區塊

接著我們登入剛剛所安裝好的系統驗證一下。
首先用WMQTT Utility登入到系統。此時當作一個發佈者
接著開啟一個ssh連線到RPi執行下列指令當作一個訂閱者
mosquitto_sub -d -t hello/world

此時再回到WMQTT Utility下面的區塊中在Topic項目輸入 hello/world ;然後再下面的框框中輸入測試訊息接著按下Publish按鈕,此時已透過WMQTT Utility將訊息法送到 hello/world 這個 Topic中了。

接著,回到剛剛ssh的訂閱者視窗,我們可以看到剛剛所送的訊息一字不漏的接收到了。

另外這個工具也可以當作訂閱者礙於篇幅這部分就不詳細說明有興趣的人在測試一下。不過這個工具不支援中文字訊息的發送

至此,完成了訊息的發佈與訂閱動作,接下來我們來實作在Android下的推播。
Android推播系統我們是利用網路上別人寫好的資源: How to Implement Push Notifications for Android

這個網站中提供了發佈工具(PHP程式)與訂閱工具(Android程式),這兩個程式可以到GitHub下載:
tokudu/AndroidPushNotificationsDemo  https://github.com/tokudu/AndroidPushNotificationsDemo
tokudu/PhpMQTTClient https://github.com/tokudu/PhpMQTTClient

Android程式的部分在eclipse上用匯入的方式就可以執行了。只要確認wmqtt.jar的 Java Build Path,以及更改 PushService.java 中第 38 行的 MQTT_HOST ,把這個IP改成RPi的IP即可。

接著安裝PhpMQTTClient,由於這是一個PHP的程式,因此我們必須在RPi上執行下列指令來安裝Apache+PHP :
sudo apt-get install apache2 php5

此時,我們可以在瀏覽器上輸入 http://RPi IP 即可看到下圖畫面:

然後我們將GitHub上的PhpMQTTClient下載後上傳到RPi上面。
接著將在RPi上解壓縮所上傳的檔案:
unzip PhpMQTTClient-master.zip
進入解壓所後的目錄:
cd PhpMQTTClient-master/
建立一個 etc 目錄:
mkdir etc
建立config.php檔案
vi etc/config.php
其內容如下:
define('MQTT_SERVER_HOST', '192.168.0.135');
define('MQTT_SERVER_POST', '1883');
?>

其中第2行定義了MQTT Host,這裡的IP請改成RPi的IP第3行不變,然後存檔。
此時用pwd指令確認還在PhpMQTTClient-master目錄下,接著在apache上建立一個名為mqtt的目錄:
sudo mkdir /var/www/mqtt
sudo mv ~/PhpMQTTClient-master/* /var/www/mqtt  (將PhpMQTTClient-master目錄下的所有檔案搬移到/var/www/mqtt)
此時用 ls /var/www/mqtt/ 確認檔案已經搬移過去。
接著用瀏覽器開啟剛才所安裝的PHP程式,此時你會見到如下圖所示的畫面:

此時,我們執行手機上的Push Demo程式,我們可以先將Start Push service按鈕按下,此時手機就會開始監聽伺服器是否有推播訊息。

接著我們會看到Your Device Target下的一組ID號碼(每支手機會不同),把這個號碼輸入到剛剛PHP網站中的上面那一格。
然後在下方輸入中英文測試訊息,接著按下Send Push Message。

此時,你會在手機上的通知訊息欄上看到所接收到剛才所輸入的訊息。

(註:上述手機的Topic是  tokudu/34b2b406165a8b0d )
至此,完成了Android推播的功能。不過再利用這個程式進行推播功能時務必先確認你的手機是在網路上,如果手機沒有在網路上的話在PHP上所輸入的資訊是會遺失不會重送。
當然,如果要確保訊息可以完整到手機的話就必須更改上述的程式了。


後記:
1. 如果你設計的推播系統除了手機當作發佈者外,也想要讓Arduino或其他MCU的Sensor也是發佈者,那麼MQTT是個不錯選擇。

2. Mosquitto官網提供Windows、Linux以及qnx系統的版本,所以除了RPi上可以執行也可以在Linux/Windows上執行,不過本篇主題是在樹梅派上所以其他平台我並沒有測試過。

3. mosquitto.conf (在/etc/mosquitto目錄下) 中的說明,本文所使用的是預設值沒有更改,如果需要更改的話相關參數請參考官網說明

4. Mosquitto也可以界接到其他的MQTT平台,詳見Displaying MQTT messages in a browser in real time說明

5. MQTT另一個常見的工具是mqtt-spy,可以到官方網站下載
在官方網站中的下方找到 Downloads ,並下載 0.1.8 - http://tinyurl.com/mqtt-spy-download/mqtt-spy-0.1.8-jar-with-dependencies.jar 這個檔案。
然後你要確認你的Java版本是1.8版的,因為這個工具只能用這個版本,然後執行下列指令就可以執行程式。
java -jar mqtt-spy-0.1.8-jar-with-dependencies.jar
這部分我還沒有進行測試過,詳細部分請參考官網的GettingStarted說明

6. 或許會由疑問,用樹梅派來做MQTT到底可以撐多少個用戶?
這個答案我概略測試過我的Raspberry Pi 2 Model B (二代,四核心)大致上能承受約3186個,實際上大約在1800~2000個用戶系統就滿載了,僅供參考。
所以,現今隨便的一台PC隨隨便便應該可以應付20萬個用戶吧!畢竟樹梅派是Linux嵌入式的教學工具能應付千百個用戶已經不錯了,如果要應付幾十萬或幾百萬用戶那還是買伺服器來做比較穩定。

參考:
Installing Mosquitto on a Raspberry Pi
http://jpmens.net/2013/09/01/installing-mosquitto-on-a-raspberry-pi/

Installing mosquitto on Raspberry Pi
http://www.xappsoftware.com/wordpress/2014/10/27/installing-mosquitto-on-raspberry-pi/

Running Mosquitto (MQTT broker) on Raspberry Pi
http://www.reddit.com/r/raspberry_pi/comments/2tbsj8/running_mosquitto_mqtt_broker_on_raspberry_pi/

Displaying MQTT messages in a browser in real time
http://blog.jonharrington.org/iot/2013/11/02/displaying-mqtt-messages-in-a-browser-in-real-time/

How to Implement Push Notifications for Android
http://tokudu.com/post/50024574938/how-to-implement-push-notifications-for-android

MQTT(一)簡介
http://blog.maxkit.com.tw/2014/01/mqtt.html
http://blog.maxkit.com.tw/search/label/MQTT

MQTT V3.1 Protocol Specification
http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html
http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/MQTT_V3.1_Protocol_Specific.pdf

Building Smarter Planet Solutions with MQTT and IBM WebSphere MQ Telemetry
http://www.redbooks.ibm.com/redbooks/pdfs/sg248054.pdf

Download ia92.zip
http://www-01.ibm.com/support/docview.wss?uid=swg24006006

Download mqtt-spy
https://code.google.com/p/mqtt-spy/

==============延伸閱讀=====================
1. Raspberry Pi 第一次接觸
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi.html

2.Raspberry Pi 網路設定
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi_23.html

3.Raspberry Pi 應用之Windows檔案伺服器
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi-windows.html

4.Raspberry Pi 應用之DLNA影音伺服器
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi-dlna.html

5.Raspberry Pi 硬體控制-- Python 語言篇
http://cheng-min-i-taiwan.blogspot.tw/2013/04/raspberry-pi-python.html

6.Raspberry Pi 硬體控制-- C 語言篇
http://cheng-min-i-taiwan.blogspot.tw/2013/04/raspberry-pi-c.html

7.Raspberry Pi 2 Model B 使用心得
http://www.cheng-min-i-taiwan.blogspot.tw/2015/02/raspberry-pi-2-model-b.html

8.Raspberry Pi 藍牙4.0應用之iBeacon 發射器
http://www.cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pi-40ibeacon.html

9.Raspberry Pi安裝MQTT之應用 -- Android訊息推播
http://www.cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pimqtt-android.html

10. Raspberry Pi安裝MQTT之IoT應用 -- Arduino示範
http://cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pimqttiot-android.html#more

9 則留言:

  1. 請問你的Rpi是怎麼測試這麼多用戶的呢?謝謝
    回覆
  2. 寫個script,用netstat去看,參考用!未必準確~
    #!/bin/bash
    c=1
    while [ $c -le 20000 ]
    do
    mosquitto_sub -d -t hello/world -k 900 &
    (( c++ ))
    done
    回覆
  3. 作者已經移除這則留言。
    回覆
  4. 哈囉 能和你 加個LINE嘛!? 想學習 MQTT的 相關事情!! 謝謝囉!
    回覆
  5. 哈囉 能跟你 交換 LINE嘛! 想學習 MQTT 相關事件!
    回覆
  6. 你好請問你知道如何建造mosquitto bridges嗎
    可以教一下我嗎
    回覆
  7. 你知道如何mosquitto bridges嗎
    可以教我一下嗎
    回覆
    回覆
    1. sorry,bridge我沒實做過....
  8. 請問我用ubuntu 32 64bit,都遇到無法持續連線,雖然有設定自動連接,可是還是會有斷線的問題,發送訊息的是一塊有wifi的板子,外網會有斷線的問題,但是內網卻是很穩定,這種情形有可以調整的地方嗎? 謝謝

Raspberry安裝QT

//----20160406---
IT 技術家 http://blog.itist.tw/p/rpi.html


來源  http://www.it610.com/article/2077145.htm

Raspberry Pi (BCM2835): Device Information

ArchitectureARMv6
CPUARM11
RAM256MB OR 512MB since October 2012 (shared with GPU)
GPUVideoCore IV
OpenGLOpenGL ES 2.0
MultimediaOpenMax IL 1.1.2
Qt 5.0 (eglfs/QPA)Supported, with OpenGL ES 2.0

Qt 5 port functional state (against Raspbian Wheezy (primary reference platform))

FeatureStateAdditional info
Hardware accelerated cursorDoneupstream
Wayland supportDoneupstream
Hardware decoding of imagesTo Do
Scenegraph tailoringTo Do
HardFP supportDoneRequires v8 patch
Qt MultimediaDoneRequires gst-omx
Webkit integrationTo Dowebgl, tex mapper


  • 開始

    首先我們先創建一個目錄來存放Qt5的源代碼以及交叉編譯所需要的所有文件,我選擇在當前用戶家目錄下創建一個叫做“opt”的目錄。
    1diveinedu@debian :~$ mkdir   /opt
    2diveinedu@debian :~$ cd   /opt
    然後,下載以下文件:
    下載Raspbian Wheezy鏡像(這裡下載  [raspberrypi.org] ):
    1diveinedu@debian :~ /opt $ wget http: //downloads .raspberrypi.org /images/raspbian/2013-02-09-wheezy-raspbian/2013-02-09-wheezy-raspbian .zip
    2diveinedu@debian :~ /opt $unzip 2013-02-09-wheezy-raspbian.zip
    下載解壓完後掛載鏡像:
    1diveinedu@debian :~ /opt sudo   mkdir   /mnt/rasp-pi-rootfs
    2diveinedu@debian:~ /opt sudo mount   -o loop,offset=62914560 2013-03-09-wheezy-raspbian.img    /mnt/rasp-pi-rootfs
    我們這不介紹交叉工具鏈的編譯,直接下載針對樹莓派優化定制的交叉編譯工具鏈(或者用github上樹​​莓派的工具鏈https://github.com/raspberrypi/tool​​s):
    1diveinedu@debian:~ /opt $ wget http: //blueocean .qmh-project.org /gcc-4 .7-linaro-rpi-gnueabihf.tbz
    2diveinedu@debian:~ /opt $   tar -xf gcc-4.7-linaro-rpi-gnueabihf.tbz
    因為上面的交叉編譯工具是32位Linux的,如果你所使用的是64位Linux的話,還需要安裝32位的運行庫軟件包:
    1diveinedu@debian:~ /opt $  sudo apt-get install ia32-libs
    如果用的是Debian Wheezy的64位系統,上面的行不通,因為Debian Wheezy 64位開啟了multiarch-support ,需要執行:
    1diveinedu@debian:~/opt$ sudo apt-get install multiarch-support
    2diveinedu@debian:~/opt$ sudo dpkg --add-architecture i386
    3diveinedu@debian:~/opt$ sudo apt-get update
    4diveinedu@debian:~/opt$ sudo apt-get install ia32-libs

    從遠程倉庫克隆一份cross-compile-tools到本地:
    1diveinedu@debian:~ /opt $ git clone git: //gitorious .org /cross-compile-tools/cross-compile-tools .git
    從遠程倉庫克隆一份Qt5的源碼庫到本地:
    1diveinedu@debian:~ /opt $ git clone git: //gitorious .org /qt/qt5 .git
    2diveinedu@debian:~ /opt $   cd qt5
    3diveinedu@debian:~ /opt/qt5 $ . /init-repository
    最後,把qtjsbackend子項目打補丁讓其支持armv6指令集的樹莓派:
    1diveinedu@debian:~ /opt/qt5 $  cd /opt/qt5/qtjsbackend
    2diveinedu@debian:~ /opt/qt5 $ git fetch https: //codereview .qt-project.org /p/qt/qtjsbackend   refs /changes/56/27256/4    && git cherry-pick FETCH_HEAD
    如果有衝突的話就解決衝突的代碼。


  • 編譯qtbase

    現在我們已經準備好了為樹莓派交叉編譯Qt5所需要的全部資源,在正式編譯之前只需要執行一個小腳本來修正一下符號鏈接和庫文件路徑設置:
    1diveinedu@debian:~ /opt/qt5 $  cd   /opt/cross-compile-tools
    2diveinedu@debian:~ /opt/qt5 $  sudo   /fixQualifiedLibraryPaths /mnt/rasp-pi-rootfs/ /opt/gcc-4 .7-linaro-rpi-gnueabihf /bin/arm-linux-gnueabihf-gcc
    進入qt5/qtbase目錄執行以下腳本進行配置和編譯工作:
    1diveinedu@debian:~ /opt/qt5 cd /opt/qt5/qtbase
    2diveinedu@debian:~ /opt/qt5/qtbase $ . /configure -opengl es2 -device linux-rasp-pi-g++ -device-option CROSS_COMPILE=~ /opt/gcc-4 .7-linaro-rpi-gnueabihf /bin /arm-linux-gnueabihf- -sysroot /mnt/rasp-pi-rootfs -opensource -confirm-license -optimized-qmake -reduce-relocations -reduce-exports -release - make libs -prefix /usr/local/qt5pi -no -pch
    3diveinedu@debian:~ /opt/qt5/qtbase make -j 4
    4diveinedu@debian:~ /opt/qt5/qtbase sudo make install

  • 編譯其他模塊

    執行到這步的時候,你已經有了針對樹莓派交叉編譯的qmake工具了,你可以一一的去交叉編譯Qt5的其他模塊了,為裡避免模塊編譯過程中可能出現的依賴錯誤,建議按照這個模塊順序去編譯: qtimageformats, qtsvg, qtjsbackend, qtscript, qtxmlpatterns, qtdeclarative, qtsensors, qt3d, qtgraphicaleffects,qtjsondb,qtlocation, qtdocgallery.
    模塊編譯相關的類似命令:
    1diveinedu@debian:~ /opt/qt5 cd qtimageformats
    2diveinedu@debian:~ /opt/qt5/qtimageformats /usr/local/qt5pi/bin/qmake .
    3diveinedu@debian:~ /opt/qt5/qtimageformats make -j4
    4diveinedu@debian:~ /opt/qt5/qtimageformats sudo make install
    把你所需要或者所想編譯的模塊都按順序執行編譯安裝命令後,所有需要的東西都安裝在了鏡像文件(raspbain wheezy image)裡面了。我們接下來就是把他燒到SD卡上去。SD卡燒寫命令:
    1diveinedu@debian:~ /opt/qt5 cd /opt/
    2diveinedu@debian:~ /opt sync sudo umount /mnt/rasp-pi-rootfs
    3diveinedu@debian:~ /opt sudo dd bs=1M if =2013-02-09-wheezy-raspbian.img of= /dev/sdc sync
    提示:/dev/sdc是我使用的SD的設備, 請根據自己的實際情況修改。

    到這裡,樹莓派的Qt5運行庫的編譯移植過程就Done了。
    後續會有例程Demo以及Qt5的QPA機制在樹莓派上的eglfs平台插件的特點介紹和傳統QtWidget程序在EGLFS環境下遇到的問題和解決分析。

    ///--------------------------------------------------end---------------------------------------------//
來源 http://wiki.qt.io/Apt-get_Qt4_on_the_Raspberry_Pi

Apt-get Qt4 on the Raspberry Pi

Tutorial : apt-get install Qt4 on the Rasperry Pi

1.apt-get

Firstly I got the development tools needed by Qt Creator in the hope it would be less heavy for the Pi to download separately.
sudo apt-get install qt4-dev-tools
Then I went for Qt Creator
sudo apt-get install qtcreator
I also installed
sudo apt-get install gcc
sudo apt-get install xterm
sudo apt-get install git-core
sudo apt-get install subversion
this gives as a result Qt Creator 2.5 with Qt 4.8.1 32 bit

Problem : no toolchain.

We can only compile for remote embedded devices and this is not the case here, because we are on the Pi and not remotely accessing it.

I added a gcc toolchain

Tools/Options > build & run > tab tool chains > button add Choose GCC
  • Then set compiler path : /usr/bin/arm-linux-gnueabihf-gcc-4.6
  • Debugger : /usr/bin/gdb
  • Mkspec : default

Qt Creator seems to detect that we are going to deploy on a remote target.

To fix this :
  • Go to menu help > about plugins
  • Uncheck device support > remote linux
  • Restart Qt Creator
  • Go to tools > options TAB > build & run > Qt versions > add "/usr/bin/qmake-qt4"
It will then show up as a desktop project in the project wizard instead of embedded.