Netty 网络阻塞客户端

Netty 网络阻塞客户端,netty,Netty,我正在使用OioClientSocketChannelFactory和 这样的管道: ClientBootstrap bootstrap = new ClientBootstrap( new OioClientSocketChannelFactory(Executors.newCachedThreadPool()) ); pipeline.addLast("encoder", new MessageEncoder()); pipeline.addLast("decoder", new

我正在使用OioClientSocketChannelFactory和 这样的管道:

ClientBootstrap bootstrap = new ClientBootstrap(
    new OioClientSocketChannelFactory(Executors.newCachedThreadPool())
);

pipeline.addLast("encoder", new MessageEncoder());
pipeline.addLast("decoder", new MessageDecoder());
pipeline.addLast("manager", new FooClientManager());
BlockingReadHandler<Message> reader = new BlockingReadHandler<Message>();
pipeline.addLast("reader", reader);
bootstrap.setPipeline(pipeline);
ClientBootstrap bootstrap=newclientbootstrap(
新的OioClientSocketChannelFactory(Executors.newCachedThreadPool())
);
addLast(“编码器”,newmessageencoder());
addLast(“解码器”,newmessagedecoder());
pipeline.addLast(“manager”,new FooClientManager());
BlockingReadHandler reader=新建BlockingReadHandler();
pipeline.addLast(“reader”,reader);
setPipeline(管道);
FooClientManager类(SimpleChannelHandler)在connect(SimpleChannelHandler.channelConnected)上发送握手消息,并负责使用来自服务器的握手回复(SimpleChannelHandler.messageReceived),而不将其传递到管道上。我不希望API的用户接收某些低级消息,这是FooClientManager的责任

预期在连接之后,API的用户现在将构造一条消息,并调用channel.write()发送消息,reader.read()阻止等待回复

我遇到的问题是FooClientManager在调用channel.write()的API用户之前没有看到握手回复,因为从未执行过read()

如果我在调用channel.write()之前调用reader.read(),它会无限期地阻塞,因为FooClientManager不会发送我试图读取的消息


处理阻塞客户端IO和管道中可能消耗消息的通道处理程序的最佳方法是什么

FooClientManager需要在握手完成时向API用户发出信号。一个选项是让API用户实现一个接口,该接口被传递到FooClientManager的构造函数中。您始终可以创建此接口的默认实现,该实现类似于未来,并允许API用户阻止,直到握手完成


另一个选项是让FooClientManager通过管道向上发送一条定制消息,表示连接已就绪。然后API用户阻塞reader.read(),直到它收到消息。

谢谢您的回答

这两种解决方案都有效。我们实现的解决方案是让FooClientManager排队写入请求,直到握手完成。然后它发送所有排队的消息

我们遇到的一个问题是,如果我们将所有写请求排队等待握手完成,那么当FooClientManaager调用channel.write()时,握手消息本身将排队,消息将通过整个管道发送。我们通过让FooClientManager构造一个消息事件并将其直接发送到管道中的下一个处理程序来解决这个问题:

ctx.sendDownstream(new DownstreamMessageEvent(ctx.getChannel(), new DefaultChannelFuture(ctx.getChannel(), false), msg, e.getChannel().getRemoteAddress()));

我很高兴你找到了解决办法。另一个技巧是,您还可以使用org.jboss.netty.channel.Channels.write(…)将消息直接写入管道中的下一个处理程序。