1. 问题现象
Channel 建立后消息发送失败:
ChannelFuture future = DeviceManager.getBootstrap().connect(); deviceChannel = future.channel(); connection.setChannel(deviceChannel); sendRegister();
2. 原因分析
Netty 中 ChannelFuture 的作用是用来保存Channel异步操作的结果。
在Netty中所有的I/O操作都是异步的。这意味着任何的I/O调用都将立即返回,而不保证这些被请求的I/O操作在调用结束的时候已经完成。
这表示IO调用后得到的对象可能是空的,也可能是未初始化完成的,如果要使用这些对象,必须确认异步调用已经完成,对象已经创建完成。
3. 解决方案
3.1 异步操作时进行同步等待(不建议使用)
ChannelFuture future = DeviceManager.getBootstrap().connect().sync();
3.2 配置监听器,异步调用完成后再使用返回对象
DeviceManager.getBootstrap().connect().addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture channelFuture) throws Exception { deviceChannel = channelFuture.channel(); if ( !deviceChannel.isActive() ) { log.warn("channel is not active, channel:{}", deviceChannel); } connection.setChannel(deviceChannel); isConnect = true; connection.setConnectAt(DateUtil.date2String(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS)); log.info("设备ID[{}]请求注册,channelid:{}",deviceId, deviceChannel.id()); sendRegister(); } });