我目前正在尝试使用netty 4.0.44.Final和rxtx在微控制器和Java应用程序之间实现一些稳定的连接。控制器会不时要求时间戳,否则它只是将传感器数据转发给我的应用程序。应用程序能够接收尽可能多的包,直到我在管道中的某个地方调用writeAndFlush()(即回答时间请求)。管道正确地在输出流上写入数据(当调用writeAndFlush()时),从那时起,我的应用程序永远不会再次接收数据,我不知道为什么。
public class WsnViaRxtxConnector extends AbstractWsnConnector{
private static final Logger LOG = LoggerFactory.getLogger(WsnViaRxtxConnector.class);
private String port;
private Provider<MessageDeserializer> deserializerProvider;
private ChannelFuture channelFuture;
public ChannelKeeper keeper;
@Inject
public WsnViaRxtxConnector(Provider<MessageDeserializer> deserializerProvider, ChannelKeeper keeper) {
this.deserializerProvider = deserializerProvider;
this.port = Configuration.getConfig().getString("rest.wsn.port");
this.keeper = keeper;
System.setProperty("gnu.io.rxtx.SerialPorts", this.port);
}
@Override
protected void run() throws Exception
{
EventLoopGroup group = new OioEventLoopGroup();
//final EventExecutorGroup group2 = new DefaultEventExecutorGroup(1500);
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(RxtxChannel.class)
.handler(new ChannelInitializer<RxtxChannel>() {
@Override
public void initChannel(RxtxChannel ch) throws Exception {
ch.pipeline().addLast(new DleStxEtxFrameDecoder(), new DleStxEtxFrameEncoder());
ch.pipeline().addLast(new IntegrityCheck(),new IntegrityCalculation());
ch.pipeline().addLast(new AesCcmDecrypter(),new AesCcmEncrypter());
ch.pipeline().addLast(deserializerProvider.get(),new MessageSerializer());
ch.pipeline().addLast(new TimeStampJockel());
}
})
.option(RxtxChannelOption.BAUD_RATE, 19200);
ChannelFuture f = b.connect(new RxtxDeviceAddress(this.port)).sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
处理程序都是非常标准的实现,并且在仅接收包时似乎有效。管道应该首先从原始数据生成一个对象,checkCRC,解密,反序列化,然后计算一些逻辑(也就是生成时间响应)。
public class TimeStampJockel extends ChannelInboundHandlerAdapter{
private static final Logger LOG = LoggerFactory.getLogger(TimeStampJockel.class);
private EventBus bus;
private ChannelKeeper keeper;
@Inject
public TimeStampJockel(){
this.bus = GlobalEventBus.getInstance();
this.keeper = keeper;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg){
LOG.debug("Creating packet from received data");
RawPacket raw = (RawPacket)msg;
//EventExecutor ex = ctx.executor();
//LOG.debug("inexecutor.EventLoop(1):" + ex.inEventLoop());
//keeper.addChannelHandlerContext(raw.getSource(),ctx);
ByteBuf buf = raw.getContent();
LOG.debug("\tBuffer: {}", HelperFunctions.getBufferAsHexString(buf));
UnsignedLong mac = UnsignedLong.fromLongBits(21);
while(buf.readerIndex()<buf.writerIndex())
{
int type = buf.readShort();
int length = buf.readShort();
ByteBuf value = buf.readBytes(length);
if(PacketType.getEnum(type).equals(PacketType.MAC))
{
mac = UnsignedLong.valueOf(value.readLong());
}
else
{
AbstractPacket packet = PacketFactory.createPacket(PacketType.getEnum(type), raw.getVersion(), raw.getPacketType(), raw.getSource(), raw.getSource(), raw.getDestination(), mac, value);
if(packet instanceof TimeReqPacket) {
TimeReqPacket timeReqPacket = (TimeReqPacket) packet;
Duration d = HelperFunctions.timeSinceYear2000();
TimeRespPacket newPacket = new TimeRespPacket(Constants.PROTOCOL_VERSION, PacketType.TIME_RESP.getValue(), packet.getGatewayAdr(),UnsignedLong.valueOf(Configuration.getConfig().getLong("rest.wsn.mac", Long.MAX_VALUE)),timeReqPacket.getMac(),timeReqPacket.getMac(),d.getStandardSeconds(),HelperFunctions.getMillisOfDuration(d));
ctx.write(newPacket);
} else {
bus.post(packet);
}
}
}
}
接收到的传感器数据被推送到Guava总线(除非是时间请求)并由其他组件处理。如果传入的包是时间请求包,则先前显示的组件应生成时间戳包,并且writeAndFlush()在流水线下。可能导致该问题的任何想法?我几乎没有想法 - 我一直在谷歌搜索过去10个小时没有有意义的结果,我没有剩下未经检查的资源。我正在使用ubuntu 16.04,提前感谢。
[编辑]我尝试通过将以下代码片段添加到最后一个管道处理程序来检查ChannelFuture
ChannelFuture f = ctx.writeAndFlush(newPacket);
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
LOG.error("Server failed to send message", future.cause());
future.channel().close();
}
}
[EDIT2]发现我的错误。这是一个网络版本的冲突。我正在使用不同项目中的多个版本的netty,并使用较旧的netty版本(4.0.13)而不是netty 4.044.final。我不知道这些版本之间有什么变化,但我很高兴现在一切正常。