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(); } });