我是Netty的新手,我决定从4.0.0开始,因为我认为应该更好,因为它更新。我的服务器应用程序应该从gps设备接收数据,过程是这样的 - 首先我收到2个字节,这是设备imei的长度,然后我接收到那个长度的imei,然后我应该发送0x01到设备,如果我想接受它的数据。在我的应答设备向我发送带有AVL协议的gps数据之后。现在我的服务器正在没有Netty工作,我想改变它以使用netty。 这就是我所做的:
我已经创建了像这样的服务器类
public class BusDataReceiverServer {
private final int port;
private final Logger LOG = LoggerFactory.getLogger(BusDataReceiverServer.class);
public BusDataReceiverServer(int port) {
this.port = port;
}
public void run() throws Exception {
LOG.info("running thread");
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new BusDataReceiverInitializer());
b.bind(port).sync().channel().closeFuture().sync();
}catch (Exception ex){
LOG.info(ex.getMessage());
}
finally {
LOG.info("thread closed");
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new BusDataReceiverServer(3129).run();
}
}
并创建了初始化类
public class BusDataReceiverInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast("imeiDecoder", new ImeiDecoder());
pipeline.addLast("busDataDecoder", new BusDataDecoder());
pipeline.addLast("encoder", new ResponceEncoder());
pipeline.addLast("imeiHandler", new ImeiReceiverServerHandler());
pipeline.addLast("busDataHandler", new BusDataReceiverServerHandler());
}
}
然后我创建了解码器和编码器以及2个处理程序。我的imeiDecoder和编码器以及ImeiReceiverServerHandler正在工作。这是我的ImeiReceiverServerHandler
public class ImeiReceiverServerHandler extends ChannelInboundHandlerAdapter {
private final Logger LOG = LoggerFactory.getLogger(ImeiReceiverServerHandler.class);
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception {
MessageList<String> imeis = msgs.cast();
String imei = imeis.get(0);
ctx.write(Constants.BUS_DATA_ACCEPT);
ctx.fireMessageReceived(msgs);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause); //To change body of overridden methods use File | Settings | File Templates.
}
}
现在,在接受之后我不明白如何继续接收gps数据并将其转发给处理程序BusDataReceiverServerHandler。 如果有人可以帮我这个或者可以提供有用的文件,我将非常感激。或者如果可以用Netty 3做到这一点,为此我也会感激不尽。
答案 0 :(得分:2)
我没有使用过Netty 4,所以我不确定我的回答是100%准确还是在Netty 4中做事的最佳方式,但你需要做的是跟踪连接/客户端会话的状态为了知道何时将消息转发给第二个处理程序。
E.g。
private enum HandlerState { INITIAL, IMEI_RECEIVED; }
private HandlerState state = HandlerState.INITIAL;
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) throws Exception
{
if (state == HandlerState.INITIAL)
{
MessageList<String> imeis = msgs.cast();
String imei = imeis.get(0);
ctx.write(Constants.BUS_DATA_ACCEPT);
state = HandlerState.IMEI_RECEIVED;
} else
{
// Forward message to next handler...
// Not sure exactly how this is done in Netty 4
// Maybe: ctx.fireMessageReceived(msgs);
// Or maybe it is:
// ctx.nextInboundMessageBuffer().add(msg);
// ctx.fireInboundBufferUpdated();
// I believe you could also remove the IMEI handler from the
// pipeline instead of having it keep state, if it is not going to do anything
// further.
}
}
因此,无论是处理程序中的跟踪状态,还是处理完成后从管道中删除处理程序,如果它不会被进一步使用。跟踪状态时,您可以将状态保留在处理程序本身中(如上所示),也可以将状态变量保存在上下文/属性映射中(但这可以在netty 4中完成)。
如果要使处理程序可共享(在多个通道中使用一个实例),则不在处理程序本身中保持状态的原因是。没有必要这样做,但如果你有大量的并发通道,可以节省一些资源。