MQTT的学习研究(二)moquette-mqtt 的使用之mqtt broker的启动
在MQTT 官网 (http://mqtt.org/software)中有众多MQTT的实现方式。具体参看官网,Moquette是基于Apache Mina 的模型的一个Java MQTT broker。使用过Mina的同学发现其实broker的启动过程就是一个Mina应用的启动。
在MQTT moquette 中采用MINA作为底层消息的传递方式
本类的目的启动MQTT moquette Broker 的方式,
本文的源代码来自 moquette-broker-0.1-jar-with-dependencies.jar 中的server类
如果想直接启动 moquette-broker-0.1-jar-with-dependencies.jar的jar文件方式
可以执行一些命令实现
java -jar moquette-broker-0.1-jar-with-dependencies.jar
google code 下载MQTT moquette Broker 地址:
http://code.google.com/p/moquette-mqtt/
GIT 下载MQTT moquette client 地址:
https://github.com/fusesource/mqtt-client
在应用程序中使用MQTT的应用:
MQTT moquette 的broker服务启动代码如下:
- package com.etrip.mqtt;
- import java.io.File;
- import java.io.IOException;
- import java.net.InetAddress;
- import java.net.InetSocketAddress;
- import org.apache.mina.core.service.IoAcceptor;
- import org.apache.mina.core.service.IoServiceStatistics;
- import org.apache.mina.core.session.IdleStatus;
- import org.apache.mina.core.session.IoSession;
- import org.apache.mina.filter.codec.ProtocolCodecFilter;
- import org.apache.mina.filter.codec.demux.DemuxingProtocolDecoder;
- import org.apache.mina.filter.codec.demux.DemuxingProtocolEncoder;
- import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
- import org.dna.mqtt.moquette.messaging.spi.impl.SimpleMessaging;
- import org.dna.mqtt.moquette.proto.ConnAckEncoder;
- import org.dna.mqtt.moquette.proto.ConnectDecoder;
- import org.dna.mqtt.moquette.proto.DisconnectDecoder;
- import org.dna.mqtt.moquette.proto.DisconnectEncoder;
- import org.dna.mqtt.moquette.proto.MQTTLoggingFilter;
- import org.dna.mqtt.moquette.proto.PingReqDecoder;
- import org.dna.mqtt.moquette.proto.PingRespEncoder;
- import org.dna.mqtt.moquette.proto.PubAckDecoder;
- import org.dna.mqtt.moquette.proto.PubAckEncoder;
- import org.dna.mqtt.moquette.proto.PubCompDecoder;
- import org.dna.mqtt.moquette.proto.PubCompEncoder;
- import org.dna.mqtt.moquette.proto.PubCompMessage;
- import org.dna.mqtt.moquette.proto.PubRecDecoder;
- import org.dna.mqtt.moquette.proto.PubRecEncoder;
- import org.dna.mqtt.moquette.proto.PubRelDecoder;
- import org.dna.mqtt.moquette.proto.PubRelEncoder;
- import org.dna.mqtt.moquette.proto.PublishDecoder;
- import org.dna.mqtt.moquette.proto.PublishEncoder;
- import org.dna.mqtt.moquette.proto.SubAckEncoder;
- import org.dna.mqtt.moquette.proto.SubscribeDecoder;
- import org.dna.mqtt.moquette.proto.UnsubAckEncoder;
- import org.dna.mqtt.moquette.proto.UnsubscribeDecoder;
- import org.dna.mqtt.moquette.proto.messages.ConnAckMessage;
- import org.dna.mqtt.moquette.proto.messages.DisconnectMessage;
- import org.dna.mqtt.moquette.proto.messages.PingRespMessage;
- import org.dna.mqtt.moquette.proto.messages.PubAckMessage;
- import org.dna.mqtt.moquette.proto.messages.PubRecMessage;
- import org.dna.mqtt.moquette.proto.messages.PubRelMessage;
- import org.dna.mqtt.moquette.proto.messages.PublishMessage;
- import org.dna.mqtt.moquette.proto.messages.SubAckMessage;
- import org.dna.mqtt.moquette.proto.messages.UnsubAckMessage;
- import org.dna.mqtt.moquette.server.MQTTHandler;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- *
- * 在MQTT moquette 中采用MINA作为底层消息的传递方式
- *
- * 本类的目的启动MQTT moquette Broker 的方式,
- *本文的源代码来自 moquette-broker-0.1-jar-with-dependencies.jar 中的server类
- * 如果想直接启动 moquette-broker-0.1-jar-with-dependencies.jar的jar文件方式
- * 可以执行一些命令实现
- * java -jar moquette-broker-0.1-jar-with-dependencies.jar
- *
- *
- * google code 下载MQTT moquette Broker 地址:
- * http://code.google.com/p/moquette-mqtt/
- *
- * GIT 下载MQTT moquette client 地址:
- * https://github.com/fusesource/mqtt-client
- *
- * @author longgangbai
- *
- *
- */
- public class MQTTBrokerProxyServer {
- private static final Logger LOG = LoggerFactory.getLogger(MQTTBrokerProxyServer.class);
- public static final String STORAGE_FILE_PATH = System.getProperty("user.home") + File.separator + "moquette_store.hawtdb";
- private IoAcceptor m_acceptor;
- SimpleMessaging messaging;
- public static void main(String[] args)
- throws IOException
- {
- new MQTTBrokerProxyServer().startServer();
- }
- protected void startServer() throws IOException
- {
- //编码协议类编码器
- DemuxingProtocolDecoder decoder = new DemuxingProtocolDecoder();
- decoder.addMessageDecoder(new ConnectDecoder());//连接编码
- decoder.addMessageDecoder(new PublishDecoder());//发布编码
- decoder.addMessageDecoder(new PubAckDecoder());//发布回执编码
- decoder.addMessageDecoder(new PubRelDecoder());
- decoder.addMessageDecoder(new PubRecDecoder());//接收编码
- decoder.addMessageDecoder(new PubCompDecoder());
- decoder.addMessageDecoder(new SubscribeDecoder());//订阅编码
- decoder.addMessageDecoder(new UnsubscribeDecoder());//取消订阅编码
- decoder.addMessageDecoder(new DisconnectDecoder());//断开连接编码
- decoder.addMessageDecoder(new PingReqDecoder());//心跳ping请求编码
- //解码协议类解码器
- DemuxingProtocolEncoder encoder = new DemuxingProtocolEncoder();
- encoder.addMessageEncoder(ConnAckMessage.class, new ConnAckEncoder());//连接解码
- encoder.addMessageEncoder(SubAckMessage.class, new SubAckEncoder());//订阅通知解码
- encoder.addMessageEncoder(UnsubAckMessage.class, new UnsubAckEncoder());//取消订阅解码
- encoder.addMessageEncoder(PubAckMessage.class, new PubAckEncoder());//发布回执解码
- encoder.addMessageEncoder(PubRecMessage.class, new PubRecEncoder());//接收解码
- encoder.addMessageEncoder(PubCompMessage.class, new PubCompEncoder());
- encoder.addMessageEncoder(PubRelMessage.class, new PubRelEncoder());
- encoder.addMessageEncoder(PublishMessage.class, new PublishEncoder());//发布解码
- encoder.addMessageEncoder(PingRespMessage.class, new PingRespEncoder());//心跳ping相应解码
- encoder.addMessageEncoder(DisconnectMessage.class,new DisconnectEncoder());//断开连接解码
- this.m_acceptor = new NioSocketAcceptor();
- //设置日志的过滤链
- this.m_acceptor.getFilterChain().addLast("logger", new MQTTLoggingFilter("SERVER LOG"));
- //设置编码的过滤链
- this.m_acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(encoder, decoder));
- //创建业务处理器类
- MQTTHandler handler = new MQTTHandler();
- //创建一个处理消息体的消息
- this.messaging = SimpleMessaging.getInstance();
- this.messaging.init();
- //设置消息体
- handler.setMessaging(this.messaging);
- //设置业务处理器类
- this.m_acceptor.setHandler(handler);
- ((NioSocketAcceptor)this.m_acceptor).setReuseAddress(true);
- ((NioSocketAcceptor)this.m_acceptor).getSessionConfig().setReuseAddress(true);
- this.m_acceptor.getSessionConfig().setReadBufferSize(2048);
- this.m_acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
- this.m_acceptor.getStatistics().setThroughputCalculationInterval(10);
- this.m_acceptor.getStatistics().updateThroughput(System.currentTimeMillis());
- //设置端口号
- this.m_acceptor.bind(new InetSocketAddress(1883));
- //获取绑定的本地的ip地址
- LOG.info("Server binded"+InetAddress.getLocalHost().getHostAddress());
- try {
- Thread.sleep(100000000000000L);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- //销毁broker对象的各种信息
- Runtime.getRuntime().addShutdownHook(new Thread()
- {
- public void run() {
- MQTTBrokerProxyServer.this.stopServer();
- }
- });
- }
- protected void stopServer() {
- LOG.info("Server stopping...");
- this.messaging.stop();
- //Mina IO 统计类
- IoServiceStatistics statistics = this.m_acceptor.getStatistics();
- statistics.updateThroughput(System.currentTimeMillis());
- System.out.println(String.format("Total read bytes: %d, read throughtput: %f (b/s)", new Object[] { Long.valueOf(statistics.getReadBytes()), Double.valueOf(statistics.getReadBytesThroughput()) }));
- System.out.println(String.format("Total read msgs: %d, read msg throughtput: %f (msg/s)", new Object[] { Long.valueOf(statistics.getReadMessages()), Double.valueOf(statistics.getReadMessagesThroughput()) }));
- //关闭相关的会话
- for (IoSession session : this.m_acceptor.getManagedSessions().values()) {
- if ((session.isConnected()) && (!session.isClosing())) {
- session.close(false);
- }
- }
- //销毁本地IoAcceptor对象
- this.m_acceptor.unbind();
- this.m_acceptor.dispose();
- LOG.info("Server stopped");
- }
- }
由 以上代码可以看出,在发布订阅,心跳检测,连接断开,连接时候都需要创建相关的协议编码器对象类中添加相关的编码器对象。
MQTTHandler类为主要broker处理发布和订阅消息的业务处理器类。
IoServiceStatistics类信息统计类。主要统计在mina应用中读写信息的统计。
上面代码主要讲解MQTT moquette的启动下面主要讲述服务段发布消息和客户端订阅接收信息的实现。
MQTT的学习研究(二)moquette-mqtt 的使用之mqtt broker的启动的更多相关文章
- MQTT的学习研究(八)基于HTTP DELETE MQTT 订阅消息服务端使用
HTTP DELETE 订阅主题请求协议和响应协议http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/topic/com.ibm.mq.csqzau ...
- MQTT的学习研究(九)基于HTTP GET MQTT 抓取消息服务端使用
官方参看文档: HTTP GET 接收主题请求协议和响应协议http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/topic/com.ibm.mq.c ...
- MQTT的学习研究(七)基于HTTP POST MQTT 发布消息服务端使用
参阅官方文档 http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/topic/com.ibm.mq.csqzau.doc/ts21220_.htm ...
- MQTT的学习研究(六) MQTT moquette 的 Blocking API 订阅消息客户端使用
* 使用 Java 为 MQ Telemetry Transport 创建订户 * 在此任务中,您将遵循教程来创建订户应用程序.订户将针对主题创建预订并接收该预订的发布. * 提供了一个示例订户应用程 ...
- MQTT的学习研究(四)moquette-mqtt 的使用之mqtt Blocking API客户端订阅并接收主题信息
在上面两篇关于mqtt的broker的启动和mqtt的服务端发布主题信息之后,我们客户端需要订阅相关的信息并接收相关的主题信息. package com.etrip.mqtt; import java ...
- MQTT协议学习研究 & Mosquitto简要教程(安装和使用)
若初次接触MQTT协议,可先理解以下概念: [MQTT协议特点]——相比于RESTful架构的物联网系统,MQTT协议借助消息推送功能,可以更好地实现远程控制. [MQTT协议角色]——在RESTfu ...
- C++的开源跨平台日志库glog学习研究(二)--宏的使用
上一篇从整个工程上简单分析了glog,请看C++的开源跨平台日志库glog学习研究(一),这一篇对glog的实现代码入手,比如在其源码中以宏的使用最为广泛,接下来就先对各种宏的使用做一简单分析. 1. ...
- MQTT的学习研究(十二) MQTT moquette 的 Future API 消息发布订阅的实现
MQTT moquette 的Server发布主题 package com.etrip.mqtt.future; import java.net.URISyntaxException; import ...
- MQTT的学习研究(十四) MQTT moquette 的 Callback API 消息发布订阅的实现
在moquette-mqtt中提供了回调callback模式的发布和订阅但是在订阅之后没有发现有消息接收的方法,参看moquette-mqtt中Block,Future式的发布订阅基础是callbac ...
随机推荐
- linux/unix 段错误捕获_转
转自:linux/unix 段错误捕获[续] 本文为“在C/C++中捕获段错误,打印出错的具体位置”的续篇,进一步解决涉及动态链接库的情况. 背景知识: ·linux/unix下动态链接库的基本原 ...
- 关于最新的Vuforia-unity3d-samples2-8-13
今天用了一下最新的Vuforia for unity3d的样例2-813版本号.导入我的unity3d之后.发现ARCamera的检视面板下非常多熟悉的元素都不见了,根本没法改动标志,如图所看到的. ...
- MongoDB(四):MongoDB连接和创建数据库
在连接MongoDB前确保启动MongoDB服务,只需要在MongoDB安装目录的bin目录下执行mongo.exe即可. 执行启动操作后,mongodb在输出一些必要信息后不会输出任何信息,之后就等 ...
- PHPstorm8 自动换行设置方法
PHPstorm是一款非常不错的PHP开发工具,有很多需要自己设置.比如,IDE常见的代码自动换行功能需要我们自己去配置才能实现. File -> Settings -> Editor ...
- 01 Developing Successful Oracle Application
本章提要-------------------------------本章是概述性章节1. 介绍了了解数据库内部结构对于开发的重要性2. 介绍了如何才能开发好的数据库应用程序------------- ...
- KBEngine 服务器端-loginapp-协议构建、解析执行详细介绍
宏宏宏 由于 C++ 是静态语言,不能像 js 一样通过函数名字符串来直接执行函数,所以将 messageId 映射到可执行函数的复杂性大大提升:KBEngine 使用了一系列精巧的「宏」来解决这个问 ...
- 微信分享SDK
网址:http://www.8ru.org/weixin-js-sdk.html 下载demo:http://demo.open.weixin.qq.com/jssdk
- BCM_SDK命令
启动bcm的sdk,会进入一个类似shell的交互界面,在其中如入命令,可以配置交换机芯片.本文主要记录一下命令: 1.端口限速命令 2.链路聚合命令 3.i2c控制命令 启动方法: /tmp/bcm ...
- PHP 初学
虚拟目录和虚拟主机的关系?虚拟主机可以设置多个,虚拟目录呢? 以为phpstorm和Intellij一样,结果不是!它直接将所有内容上传(部署)到服务器即可,不像Intellij那样还调用服务器?? ...
- 第三百二十一节,Django框架,发送邮件
第三百二十一节,Django框架,发送邮件 全局配置settings.py EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' ...