/*** netty服务器的监听 处理器
*
*@authorflm 2017年10月27日*/
public class IOHandler extendsChannelInboundHandlerAdapter {private static Logger log = Logger.getLogger(IOHandler.class);//netty AttributeKey 相对于 web session【重要】
public static final AttributeKey KEY = AttributeKey.valueOf("IO");privateProducer producer;publicIOHandler(Producer producer){this.producer=producer;
}/*** 读取数据*/@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throwsException {
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);
}/*** 客户端 注册*/@Overridepublic void channelRegistered(ChannelHandlerContext ctx) throwsException {super.channelRegistered(ctx);
log.info(String.format("# client registered...: %s ...", ctx.channel()));
DeviceSession session= newDeviceSession(ctx.channel());//绑定客户端到SOCKET
ctx.channel().attr(KEY).set(session);
}/*** 客户端 失去连接*/@Overridepublic void channelInactive(ChannelHandlerContext ctx) throwsException
{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));
}
}/*** 心跳机制 用户事件触发*/@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throwsException
{if (evt instanceofIdleStateEvent)
{
IdleStateEvent e=(IdleStateEvent) evt;//检测 是否 这段时间没有和服务器联系
if (e.state() ==IdleState.ALL_IDLE)
{//检测心跳
checkIdle(ctx);
}
}super.userEventTriggered(ctx, evt);
}/*** 报错 处理事件*/@Overridepublic voidexceptionCaught(ChannelHandlerContext ctx, Throwable cause)throwsException {
log.error("# 客户端连接 Netty 出错...");
cause.printStackTrace();//关闭连接
closeConnection(ctx);
}