首先,我将解释我正在尝试实施的情况和逻辑:
我有多个线程,每个线程都有效,一些名为Result
的对象进入队列QueueToSend
我的NettyClient
在线程中运行,并且每1毫秒从Result
获取QueueToSend
并且应该连接到服务器并发送一条消息,该消息是从Result
创建的。
我也需要这个连接是异步的。因此,我需要Result
知道NettyHandler
列表,以便发送正确的消息并处理正确的结果,然后再发送回复。
所以我初始化NettyClient
bootstrap
bootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
并在应用启动时设置管道一次。
然后,每隔几毫秒我从Result
获取QueueToSend
对象并连接到服务器
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,port);
ResultConcurrentHashMap.put(future.getChannel().getId(), result);
我决定使用静态ConcurrentHashMap
来保存从与频道相关的QueueToSend
中获取的每个结果对象。
第一个问题发生在方法channelConnected的NettyHandler
中,当我尝试将Result
对象与来自ResultConcurrentHashMap
的频道相关联时。
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
Channel channel = ctx.getPipeline.getChannel();
Result result = ResultConcurrentHashMap.get(channel.getId());
}
但有时result
为空(50个中的1个),甚至认为它应该在ResultConcurrentHashMap
中。我认为这是因为channelConnected
事件发生在NettyClient
运行此代码之前:
ResultConcurrentHashMap.put(future.getChannel().getId(), result);
如果我在本地主机上运行NettyServer
和NettyClient
,可能不会出现,但远程地,建立连接需要更多时间。但是我需要一个解决这个问题的方法。
另一个问题是我每1毫秒异步发送一次消息,我想消息可能是混合的,服务器无法正确读取它们。如果我一个接一个地运行它们就可以了:
future.getChannel().getCloseFuture().awaitUninterruptibly();
但我需要asynchromus发送,处理正确的结果,与频道相关并发送回复。 我应该实施什么?
答案 0 :(得分:2)
ChannelFutures在事件被触发之前异步执行。例如,在触发频道连接事件之前,将完成频道连接未来。
所以你必须在调用bootstrap.connect()之后注册一个通道未来的监听器,并在监听器中编写你的代码来初始化HashMap,然后它将对处理程序可见。
ChannelFuture channelFuture = bootstrap.connect(remoteAddress, localAddress);
channelFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
resultConcurrentHashMap.put(future.getChannel().getId(), result);
}
});