netty发送和接收数据handler处理器
netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter
一般用netty来发送和接收数据都会继承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter这两个抽象类,那么这两个到底有什么区别呢?
其实用这两个抽象类是有讲究的,在客户端的业务Handler继承的是SimpleChannelInboundHandler,而在服务器端继承的是ChannelInboundHandlerAdapter。
最主要的区别就是SimpleChannelInboundHandler在接收到数据后会自动release掉数据占用的Bytebuffer资源(自动调用Bytebuffer.release())。而为何服务器端不能用呢,因为我们想让服务器把客户端请求的数据发送回去,而服务器端有可能在channelRead方法返回前还没有写完数据,因此不能让它自动release。
handler处理器 内置 方法
channelActive
通道激活时触发,当客户端connect成功后,服务端就会接收到这个事件,从而可以把客户端的Channel记录下来,供后面复用
channelRead
这个必须用啊,当收到对方发来的数据后,就会触发,参数msg就是发来的信息,可以是基础类型,也可以是序列化的复杂对象。
channelReadComplete
channelRead执行后触发
exceptionCaught
出错是会触发,做一些错误处理
继承 ChannelInboundHandlerAdapter 具体的例子

/**
* netty服务器的监听 处理器
*
* @author flm 2017年10月27日
*/
public class IOHandler extends ChannelInboundHandlerAdapter { private static Logger log = Logger.getLogger(IOHandler.class); //netty AttributeKey 相对于 web session【重要】
public static final AttributeKey<DeviceSession> KEY = AttributeKey.valueOf("IO"); private Producer producer; public IOHandler(Producer producer){
this.producer=producer;
} /**
* 读取数据
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { DeviceSession session = ctx.channel().attr(KEY).get(); // 检测是否 自己注册的 客户端 ByteBuf buffer=(ByteBuf) msg; if (buffer == null||session == null) {
closeConnection(ctx); // 关闭连接
} MsgEntity msgEntity = new MsgEntity(buffer); // 解码 buffer 封装 msgEntity
log.info("# Accept Client data :"+msgEntity.toString()); if (MsgType.UNKNOW == msgEntity.getMsgType()) {
log.info("# 客户端 发送数据 类型未定义... :"+msgEntity.toString());
return;
} if(!session.isActivity()){
session.setActivity(true);
session.setImei(msgEntity.getImei());
SessionManager.getSingleton().addClient(session);
}
producer.putData(msgEntity); } /**
* 客户端 注册
*/
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
super.channelRegistered(ctx); log.info(String.format("# client registered...: %s ...", ctx.channel())); DeviceSession session = new DeviceSession(ctx.channel());
// 绑定客户端到SOCKET
ctx.channel().attr(KEY).set(session);
} /**
* 客户端 失去连接
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception
{
super.channelInactive(ctx); log.info(String.format("# client out... : %s", ctx.channel()));
DeviceSession session = ctx.channel().attr(KEY).getAndSet(null); // 移除 session 并删除 该客户端
SessionManager.getSingleton().removeClient(session, true); if(session.getDeviceID() != null)
{
// producer.onData(new Request(new RootMessage(MessageType.LOGOUT, null, null), session));
} } /**
* 心跳机制 用户事件触发
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
{
if (evt instanceof IdleStateEvent)
{
IdleStateEvent e = (IdleStateEvent) evt; //检测 是否 这段时间没有和服务器联系
if (e.state() == IdleState.ALL_IDLE)
{
//检测心跳
checkIdle(ctx);
}
} super.userEventTriggered(ctx, evt);
} /**
* 报错 处理事件
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception { log.error("# 客户端连接 Netty 出错...");
cause.printStackTrace();
//关闭连接
closeConnection(ctx);
}

netty发送和接收数据handler处理器的更多相关文章
- Netty——高级发送和接收数据handler处理器
netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和 ...
- 手把手教你Android手机与BLE终端通信--连接,发送和接收数据
假设你还没有看上一篇 手把手教你Android手机与BLE终端通信--搜索,你就先看看吧,由于这一篇要接着讲搜索到蓝牙后的连接.和连接后的发送和接收数据. 评论里有非常多人问假设一条信息特别长,怎么不 ...
- [Socket网络编程]由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
原文地址:http://blog.sina.com.cn/s/blog_70bf579801017ylu.html,记录在此方便查看 解决办法: MSDN的说明: Close 方法可关闭远程主机连接, ...
- udp网络程序-发送、接收数据
1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...
- socket 错误之:OSError: [WinError 10057] 由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
出错的代码 #server端 import socket import struct sk=socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen( ...
- TCP程序中发送和接收数据
这里我们来探讨一下在网络编程过程中,有关read/write 或者send/recv的使用细节.这里有关常用的阻塞/非阻塞的解释在网上有很多很好的例子,这里就不说了,还有errno ==EAGAIN ...
- MPTCP 源码分析(四) 发送和接收数据
简述: MPTCP在发送数据方面和TCP的区别是可以从多条路径中选择一条 路径来发送数据.MPTCP在接收数据方面与TCP的区别是子路径对无序包 进行重排后,MPTCP的mpcb需要多所有子 ...
- 31.用python中的serial向串口发送和接收数据(案例一)
代码功能说明:1.向串口助手发送十六进制数据:0X01,0X03,0X00,0X00,0X00,0X01,0X84,0X0A: 2.用串口助手向代码发送数据,并将发送过来的数据保存在数据库中,按数据和 ...
- java-TCP协议发送和接收数据
TCP协议接收数据的步骤: A:创建接收数据的Socket对象 创建对象的时候要指定端口 B:监听客户端连接 等待客户端连接 C:获取Socket对象的输入流(字节流) D:读数据,并显示在控制台 E ...
随机推荐
- Tomcat 基本配置
1.配置虚拟目录映射 推荐在 /conf/Catalina/localhost 下新建rand.xml方式建立虚拟目录 其中rand将会被当作映射对象,即外部访问路径. 例子:blog.xml < ...
- 最小化或关闭Outlook2013到系统托盘
https://community.spiceworks.com/how_to/36214-minimize-and-or-close-outlook-to-taskbar 要注意里面提到的以管理员权 ...
- SPSS学习系列之SPSS Modeler的帮助文档怎么调出来使用?
不多说,直接上干货! 欢迎大家,加入我的微信公众号:大数据躺过的坑 人工智能躺过的坑 同时,大家可以关注我的个人博客: http://www.cnblogs.com/z ...
- InterView之PHP2
PHP 理论知识 常用的超全局变量(8个) $_GET ----->get传送方式 $_POST ----->post传送方式 $_REQUEST ----->可以接收到get和po ...
- 哪个先执行:@PostConstruct和@Bean的initMethod?
结论: /** * step1:执行构造函数 * step2:执行使用@PostConstruct注解修饰的方法[如果有多个,则执行顺序不确定] * step3:执行@Bean注解中initMetho ...
- Java Bad version
Eclipse的三个地方需要重新设置: 在工程上点右键,选属性,三个地方: Java Build Path Java Compiler Project Facets:这个地方还可以设置tomcat的r ...
- pictureBox控件获得图片路径的三种方法及自适应大小属性
1.绝对路径: this.pictureBox2.Image=Image.FromFile("D:\\001.jpg"); 2.相对路径: Application.StartupP ...
- Jsp&Servlet入门级项目全程实录第7讲
惯例广告一发,对于初学真,真的很有用www.java1234.com,去试试吧! 1.获取搜索条件值 function searchStudent(){ $('#dg').datagrid('load ...
- 微信小程序: 编译.wxss文件错误解决
博主最近又重新开始捡起微信小程序,想做点自己的东西.了解到最近小程序工具有做更新,就顺手更新了最新的版本,功能比之前强大了不少! 更新归更新,更新后控制台就一直报下面这个错误: 解决办法 有问题总 ...
- Java中Date与String的相互转换
我们在注册网站的时候,往往需要填写个人信息,如姓名,年龄,出生日期等,在页面上的出生日期的值传递到后台的时候是一个字符串,而我们存入数据库的时候确需要一个日期类型,反过来,在页面上显示的时候,需要从数 ...