Mqtt研究与测试

由于功耗的原因,Wifi模块的设备想用Mqtt协议与云平台进行通信,最近研究Mqtt协议。

由于之前在Rabbitmq中验证过Mqtt插件,为了简单起见,以及迎合物联网的常规做法,也积极拥抱Mqtt。

首先,测试环境是通过docker容器跑的rabbitmq服务,这样对现有服务器的影响最小。

由github上的代码自动生成rabbitmq+ssl的镜像:https://github.com/soho-smarthome/rabbitmq-with-ssl-in-docker.git,省去了自己创建秘钥的过程,利于测试。

1. git clone https://github.com/soho-smarthome/rabbitmq-with-ssl-in-docker.git 
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, <<"admin">>},
                  {default_pass, <<"admin">>},
                  {allow_anonymous, false},
                  {vhost, <<"/">>},
                  {exchange, <<"amq.topic">>},
                  {subscription_ttl, 1800000},
                  {prefetch, 10},
                  {ssl_listeners, [8883]},
                  {tcp_listeners, [1883]},
                  {tcp_listen_options, [{backlog, 4096}, {nodelay, true}]}]},
        {rabbitmq_management, [{listener, [{port, 15672}]}]}
].

#需要enable web和mqtt通过新建enable_plugins文件实现
vim enabled_plugins
[rabbitmq_management,rabbitmq_mqtt].

#新建admin用户,int vhost通过init.sh实现
vim init.sh
#!/bin/bash

(sleep 5 ; \
rabbitmqctl add_user $RABBITMQ_USER $RABBITMQ_PASSWORD ; \
rabbitmqctl set_user_tags $RABBITMQ_USER administrator ; \
rabbitmqctl add_vhost $V_HOST; \
rabbitmqctl set_permissions -p / $RABBITMQ_USER ".*" ".*" ".*" ; \
echo "*** User '$RABBITMQ_USER' with password '$RABBITMQ_PASSWORD' completed. ***") &
rabbitmq-server $@

#修改Dockerfile
ENV RABBITMQ_USER admin
ENV RABBITMQ_PASSWORD admin
ENV V_HOST int
ADD init.sh /init.sh
RUN ["chmod", "+x", "/init.sh"]
CMD /bin/bash /home/generate-client-keys.sh && /bin/bash /init.sh

#注意init.sh要在rabbitmq服务启动后再运行。

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 --name myrbmqtt rabbitmq-with-ssl:latest
#ls /tmp/docker-test
java client用到了里面的:key-store.p12和trust-store.p12


这里有问题: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)

两种解决办法:
1. 导入java/lib/security,先找到java的根目录,比如:D:\openjdk8\jre\lib\security,然后在当前目录下运行cmd:
keytool -import -file D:\mqtt\server-cert.pem -keystore cacerts -alias server
该命令支持pem格式,不支持p12格式文件。
这里的server-cert.pem为服务端的证书
然后在创建SSLSocketFactory时,可以不用传TrustManager[],即ssl.init(kmf.getKeyManagers(), null, null);
2. 直接根据client目录中的,key-store.p12和trust-store.p12分别作为客户端的证书,服务端的证书。

 

由于镜像打包好后,可以移植,不需要每个环境都重新创建,这里通过docker save命令保存

#将镜像打包成tar文件
docker save rabbitm-with-ssl | gzip > rabbitmq-ssl.tar.gz
#将tar文件还原为镜像
docker load -i rabbitmq-ssl.tar.gz

通过docker命令运行镜像

mkdir -p /tmp/docker-test && rm -rf /tmp/docker-test/*

&& docker run -d --rm -p 12000:5671 -p 12001:5672 -p 12002:15672 -p 12003:8883 -p 12004:1883 -v /tmp/docker-test:/home/client --name myrbmqtt rabbitmq-with-ssl:latest

转载于:https://my.oschina.net/beyondken/blog/3049543

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值