netty+mqtt
package io.mqtt.server;
import io.mqtt.tool.ConfigService;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import io.netty.util.internal.logging.Log4JLoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class Server {
private static final InternalLogger logger = InternalLoggerFactory
.getInstance(Server.class);
private int port;
// private final int port = ConfigService.getIntProperty("tcp.port", 1883);
private final int httpPort = ConfigService
.getIntProperty("http.port", 8080);
private List<Channel> channels = new ArrayList<Channel>();
private EventLoopGroup bossGroup = new NioEventLoopGroup(1);
private EventLoopGroup workerGroup = new NioEventLoopGroup();
public Server(int port) {
this.port = port;
}
private ServerBootstrap getDefaultServerBootstrap() {
ServerBootstrap server = new ServerBootstrap();
server.group(bossGroup, workerGroup)
.option(ChannelOption.SO_BACKLOG, 1000)
.option(ChannelOption.TCP_NODELAY, true)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.SO_KEEPALIVE, true);
return server;
}
public ChannelFuture run() throws Exception {
InternalLoggerFactory.setDefaultFactory(new Log4JLoggerFactory());
Channel channle = getDefaultServerBootstrap()
.childHandler(new TcpChannelInitializer()).bind(port).sync()
.channel();
channels.add(channle);
logger.info("mqtt.io tcp server started at port " + port + '.');
ChannelFuture future = getDefaultServerBootstrap().childHandler(
new HttpChannelInitializer()).bind(httpPort);
Channel httpChannel = future.sync().channel();
channels.add(httpChannel);
logger.info("mqtt.io websocket server started at port " + httpPort
+ '.');
return future;
}
public void destroy() {
logger.info("destroy mqtt.io server ...");
for (Channel channel : channels) {
channel.close();
}
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
public static void main(String[] args) throws Exception {
// for (int i = 0; i < 5; i++) {
new ServerThread(65432 + (0 * 2)).start();
// }
}
}
package io.mqtt.handler;
import io.mqtt.processer.ConnectProcesser;
import io.mqtt.processer.DisConnectProcesser;
import io.mqtt.processer.PingReqProcesser;
import io.mqtt.processer.PublishProcesser;
import io.mqtt.processer.SubscribeProcesser;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.ReadTimeoutException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import io.mqtt.processer.*;
import org.meqantt.message.ConnAckMessage;
import org.meqantt.message.ConnAckMessage.ConnectionStatus;
import org.meqantt.message.DisconnectMessage;
import org.meqantt.message.Message;
import org.meqantt.message.Message.Type;
import org.meqantt.message.PingRespMessage;
public class MqttMessageHandler extends ChannelInboundHandlerAdapter {
private static PingRespMessage PINGRESP = new PingRespMessage();
private static final Map<Message.Type, Processer> processers;
static {
Map<Message.Type, Processer> map = new HashMap<Message.Type, Processer>(
6);
map.put(Type.CONNECT, new ConnectProcesser());
map.put(Type.PUBLISH, new PublishProcesser());
map.put(Type.SUBSCRIBE, (Processer) new SubscribeProcesser());
map.put(Type.UNSUBSCRIBE, (Processer) new UnsubscribeProcesser());
map.put(Type.PINGREQ, new PingReqProcesser());
map.put(Type.DISCONNECT, (Processer) new DisConnectProcesser());
processers = Collections.unmodifiableMap(map);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable e)
throws Exception {
try {
if (e.getCause() instanceof ReadTimeoutException) {
ctx.write(PINGRESP).addListener(
ChannelFutureListener.CLOSE_ON_FAILURE);
} else {
ctx.channel().close();
}
} catch (Throwable t) {
t.printStackTrace();
ctx.channel().close();
}
e.printStackTrace();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object obj)
throws Exception {
//MQTT MESSAGE
Message msg = (Message) obj;
// server收到clinet 的MQTT数据包,并获取MQTT的消息类型
Processer p = processers.get(msg.getType());
if (p == null) {
return;
}
//根据特定消息类型解析消息包
Message rmsg = p.proc(msg, ctx);
if (rmsg == null) {
return;
}
//根据消息处理结果,向clinet做出回应
if (rmsg instanceof ConnAckMessage
&& ((ConnAckMessage) rmsg).getStatus() != ConnectionStatus.ACCEPTED) {
ctx.write(rmsg).addListener(ChannelFutureListener.CLOSE);
} else if (rmsg instanceof DisconnectMessage) {
ctx.write(rmsg).addListener(ChannelFutureListener.CLOSE);
} else {
ctx.write(rmsg).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
}
//client
package com.test.client;
import org.eclipse.paho.client.mqttv3.*;
public class SubscribeMessage implements MqttCallback {
private MqttClient client;
public SubscribeMessage() {
}
public static void main(String[] args) {
// String tcpUrl = "tcp://127.0.0.1:1883";
// String clientId = "sub-msg/client1";
// String topicName = "sub/client1";
//
// new SubscribeMessage().doDemo(tcpUrl, clientId, topicName);
// for (int j = 0; j < 5; j++) {
for (int i = 0; i < 10000; i++) {
new SubscribeThread("client_" + 0 + i, "tcp://127.0.0.1:" + (65432 + 0 * 2)).start();
}
// }
}
public void doDemo(String tcpUrl, String clientId, String topicName) {
try {
client = new MqttClient(tcpUrl, clientId);
MqttConnectOptions mqcConf = new MqttConnectOptions();
mqcConf.setConnectionTimeout(300);
mqcConf.setKeepAliveInterval(1000);
client.connect(mqcConf);
client.setCallback(this);
client.subscribe(topicName);
} catch (MqttException e) {
e.printStackTrace();
}
}
public void connectionLost(Throwable cause) {
cause.printStackTrace();
}
public void messageArrived(String topic, MqttMessage message)
throws Exception {
System.out.println("[GOT PUBLISH MESSAGE] : " + message);
}
public void deliveryComplete(IMqttDeliveryToken token) {
}
}
netty+mqtt的更多相关文章
- tcp 高性能服务, netty,mqtt
1. io 线程不要有比较长的服务. 全部异步化. [1] netty 权威指南上只是说业务复杂时派发到业务线程池种. 共用的线程池最好都轻量. 多层线程池后, 下层的可以进行隔离. 这个是 mqtt ...
- 一篇关于Maven项目的jar包Shell启动脚本
使用Maven作为项目jar包依赖的管理,常常会遇到命令行启动,笔者也是哥菜鸟,在做微服务,以及服务器端开发的过程中,常常会遇到项目的启动需要使用main方法,笔者潜心的研究了很多博客,发现大多写的都 ...
- spring系列框架篇-承接各类型中小型项目-期待与您的长期合作!
框架选型: 1.基本框架:springboot2.2+springcloud(Hoxton.M2)+nacos (所有公共模块全部使用 starter 方式依赖) 2.授权及权限:oauth2+jwt ...
- Netty实现高性能IOT服务器(Groza)之手撕MQTT协议篇上
前言 诞生及优势 MQTT由Andy Stanford-Clark(IBM)和Arlen Nipper(Eurotech,现为Cirrus Link)于1999年开发,用于监测穿越沙漠的石油管道.目标 ...
- 基于Netty的IdleStateHandler实现Mqtt心跳
基于Netty的IdleStateHandler实现Mqtt心跳 IdleStateHandler解析 最近研究jetlinks编写的基于Netty的mqtt-client(https://githu ...
- Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- Netty_Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- 【netty】Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- Netty版本升级血泪史之线程篇
1. 背景 1.1. Netty 3.X系列版本现状 根据对Netty社区部分用户的调查,结合Netty在其它开源项目中的使用情况,我们可以看出目前Netty商用的主流版本集中在3.X和4.X上,其中 ...
随机推荐
- grunt小教程
本人的博客写了grunt的小教程,从零开始,一步一步的通过例子讲解,希望喜欢的同学给我的github上加颗星,谢谢! github地址: https://github.com/manlili/grun ...
- Oracle可能会遇到问题和解决方法
1.plsql developer查询一列用中文,出现乱码 添加环境变量NLS_LANG = SIMPLIFIED CHINESE_CHINA.ZHS16GBK->软件重启 2.ORA-1251 ...
- SpringCloud-服务的注册与发现(Eureka)
SpringCloud 简介 SpringCloud为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运行环境简 ...
- java的远程访问接口的实例
被别人远程调用和自己远程调用别人接口的理解: 被别人调用接口:其实没有什么神秘的,就是我们写一个正常的方法提供一个访问路径. 调用别人的接口:本质时一个Request请求,实际要使用到javax.ne ...
- ajax调试小技巧
在编写ajax时出现了问题,通过myXmlHttpRequest.responseXML无法获取值. 可以尝试打印出responseText的值.截图如下所示:
- 分享知识-快乐自己:Shrio 案例Demo概述
Shiro 权限认证核心: POM:文件: <!--shiro-all--> <dependency> <groupId>org.apache.shiro</ ...
- 使用mybatis-generator插件结合tk.mybatis自动生成mapper二三事
本篇文章将介绍使用spring boot框架,引入mybatis-generator插件,结合tk.mybatis自动生成Mapper和Entity的一整套流程,其中包括最重要的踩坑与填坑. ...
- hibernate的update、merge和saveOrUpdate的区别(转)
1.首先 saveOrUpdate返回void 也就是什么都不返回 而merge会返回一个对象 2.其次 saveOrUpdate的做法是:自动判断该对象是否曾经持久化过,如果曾持久化过则使用upda ...
- list dict set comprehension 列表推导式 (字典推导式,集合推导式)
从一个list生成新的list [ word.upper() for word in 'hellO worlD!' ] 简单的语法,如果不用list comprehension, 则要用更长的代码. ...
- ACM学习历程—UESTC 1217 The Battle of Chibi(递推 && 树状数组)(2015CCPC C)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1217 题目大意就是求一个序列里面长度为m的递增子序列的个数. 首先可以列出一个递推式p(len, i) = ...