1. 程式人生 > >Mqtt研究與測試

Mqtt研究與測試

由於功耗的原因,Wifi模組的裝置想用Mqtt協議與雲平臺進行通訊,最近研究Mqtt協議。

由於之前在Rabbitmq中驗證過Mqtt外掛,為了簡單起見,以及迎合物聯網的常規做法,也積極擁抱Mqtt。

首先,測試環境是通過docker容器跑的rabbitmq服務,這樣對現有伺服器的影響最小。

由github上的程式碼自動生成rabbitmq+ssl的映象:https://github.com/roboconf/rabbitmq-with-ssl-in-docker,省去了自己建立祕鑰的過程,利於測試。

1. git clone https://github.com/roboconf/rabbitmq-with-ssl-in-docker
2. cd rabbitmq-with-ssl-in-docker && cd tests && ./build.sh

檢視Dockerfile發現用的基礎映象是rabbitmq:3.6.6

E: The method driver /usr/lib/apt/methods/https could not be found.

需要換成rabbitmq:3.6.16,同時因為需要web頁面,且啟用mqtt,需要修改rabbitmq.conf檔案

#vim rabbitmq.conf
[
        { rabbit, [
                { loopback_users, [ ] },
                { tcp_listeners, [5672] },
                { ssl_listeners, [5671] },
                { ssl_options, [
                    {cacertfile, "/home/testca/cacert.pem"},
                    {certfile, "/home/server/cert.pem"},
                    {keyfile, "/home/server/key.pem"},
                    {verify, verify_peer},
                    {fail_if_no_peer_cert, false},
                    {versions, ['tlsv1.2', 'tlsv1.1', 'tlsv1']}
                ]}
        ] },
        {rabbitmq_mqtt, [{default_user, <<"guest">>},
                  {default_pass, <<"guest">>},
                  {allow_anonymous, false},
                  {vhost, <<"/">>},
                  {exchange, <<"mqtt.lock">>},
                  {subscription_ttl, 1800000},
                  {prefetch, 10},
                  {ssl_listeners, [8883]},
                  {tcp_listeners, [1883]},
                  {tcp_listen_options, [{backlog, 4096}, {nodelay, true}]}]},
        {rabbitmq_management, [{listener, [{port, 15672}]}]}
].

#vim Dockerfile,需要enable web和mqtt外掛
CMD /bin/bash /home/generate-client-keys.sh && rabbitmq-server && rabbitmq-plugins enable rabbitmq_management && rabbitmq-plugins enable rabbitmq_mqtt

rabbitmq映象建立成功後,通過docker命令啟動

#這裡將容器中的/home/client目錄中的客戶端證書資訊映射出來,便於client端獲取
mkdir -p /tmp/docker-test && rm -rf /tmp/docker-test/* && docker run -d --rm -p 5671:5671 -p 5672:5672 -p 15672:15672 -p 8883:8883 -p 1883:1883 -v /tmp/docker-test:/home/client rabbitmq-with-ssl:latest
#ls /tmp/docker-test
java client用到了裡面的:key-store.p12和trust-store.p12


這裡有問題:1. Dockerfile中新增web和mqtt外掛命令不生效? 2. java client需要呼叫如下命令匯入信任庫,否則報錯

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Exception in thread "main" 客戶機未連線 (32104)

2中解決辦法:
1. 匯入java/lib/security
keytool -import -file D:\mqtt\server-cert.pem -keystore cacerts -alias server
這裡的server-cert.pem為服務端的證書
然後在建立SSLSocketFactory時,可以不用傳TrustManager[],即ssl.init(kmf.getKeyManagers(), null, null);
2. 直接根據client目錄中的,key-store.p12和trust-store.p12分別作為客戶端的證書,服務端的證書。