synchronous client send/rcv help
Jason Ward
jward.dww at gmail.com
Wed Nov 18 17:24:44 EST 2009
I'm looking for some advice on a good design for the following problem.
I have a need to perform an app-level handshake once the channel is
connected. I've implemented this via a handshake method call fired from
the channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) of
my IoHandler (extending SimpleChannelUpstreamHandler).
The crux of the issue is a need for this app-level handshake to occur
synchronously blocking each subsequent send (in the handshake) until a
previous response from the peer is rcvd and validated. I've found that
blocking during my handshake method in fact blocks the I/O thread
altogether. I can see the peer actually receives the req and sends a
response, but a corresponding messageReceived(ChannelHandlerContext ctx,
MessageEvent e) isn't fired until after my originating caller times
out... which just so happens to initiate a disconnect and disposal of
resources as well.
I can easily workaround this issue by chaining messageReceived
callbacks, but I'm looking for a more elegant solution. Does anyone have
advice on how I can pull this off? Is there any example of how to force
only some requests to be blocking? I've seen the thread on the forum
where Trustin indicates adding a LinkedBlockingQueue is a solution, but
the original poster's use-case is quite different from mine in that all
requests needed to be blocking, and as best I understand it, I'm
effectively doing the same thing but creating a problem because I'm
calling my blocking method from channelConnected()... altho I might be
totally wrong.
Any advice is greatly appreciated.
Note : Because this might be a simple problem with my I/O thread pools,
I'll include my client code here (only slightly redacted for protected
info).
ClientSocketChannelFactory factory = new
NioClientSocketChannelFactory(
Executors.newCachedThreadPool(new
NamedThreadFactory("NioClientSocketChannelFactoryBoss_"+name)),
Executors.newCachedThreadPool(new
NamedThreadFactory("NioClientSocketChannelFactory_"+name))
);
bootstrap = new ClientBootstrap(factory);
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("keepAlive", true);
OrderedMemoryAwareThreadPoolExecutor threadPool = new
OrderedMemoryAwareThreadPoolExecutor(
corePoolSize, 0, 0, keepAliveTime, TimeUnit.SECONDS,
new NamedThreadFactory("XXX"+name));
ChannelPipeline pipeline = bootstrap.getPipeline();
pipeline.addLast("exec", new ExecutionHandler(threadPool));
pipeline.addLast("decoder", new AsyncMSGIoDecoder());
pipeline.addLast("encoder", new AsyncMSGIoEncoder());
pipeline.addLast("handler", new MSGIoHandler(this));
channelFuture = bootstrap.connect(new
InetSocketAddress(host, port));
Thanks in advance,
JW
More information about the netty-users
mailing list