使用ExecutionHandler对receiveMessage进行多线程处理

时间:2012-06-07 07:10:41

标签: java netty

我的PipelineFactory

private final ExecutionHandler exeHandler = new ExecutionHandler(new MemoryAwareThreadPoolExecutor (1, 0, 0, 20, TimeUnit.SECONDS, Executors.defaultThreadFactory()));

public ChannelPipeline getPipeline() throws Exception {
  ChannelPipeline pipeline = Channels.pipeline();
  pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
  pipeline.addLast("FixedLengthStringDecoder",new FixedLengthStringDecoder(4,CharsetUtil.UTF_8));
  pipeline.addLast("decode", new StringDecoder(CharsetUtil.UTF_8)); 
  pipeline.addLast("execution",exeHandler);
  pipeline.addLast("process", this.getHandler());
  return pipeline;
}

我的处理程序

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
    //i write constructedMessage to the client;
    e.getChannel().write(constructMessage(e.getMessage().toString()));
}

问题在于NioWorker:

  private boolean read(SelectionKey k) {
    ...
    if (readBytes > 0) {
        bb.flip();

        final ChannelBufferFactory bufferFactory =
            channel.getConfig().getBufferFactory();
        final ChannelBuffer buffer = bufferFactory.getBuffer(readBytes);
        buffer.setBytes(0, bb);
        buffer.writerIndex(readBytes);

        recvBufferPool.release(bb);

        // Update the predictor.
        predictor.previousReceiveBufferSize(readBytes);

        // Fire the event.
        fireMessageReceived(channel, buffer);
    } else {
        recvBufferPool.release(bb);
    }

    if (ret < 0 || failure) {
        k.cancel(); 
        close(channel, succeededFuture(channel));  //here close 
        return false;
    }

fireMessageReceived(channel,buffer)在新线程中执行, 但主要的nioworker线程将关闭通道, 所以当我在messageReceived()方法中将消息写入客户端时,

java.nio.channels.ClosedChannelException
at org.jboss.netty.channel.socket.nio.NioWorker.cleanUpWriteBuffer(NioWorker.java:645)
at org.jboss.netty.channel.socket.nio.NioWorker.writeFromUserCode(NioWorker.java:372)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:137)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:76)
at org.jboss.netty.channel.Channels.write(Channels.java:632)
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:70)
at org.jboss.netty.handler.execution.ExecutionHandler.handleDownstream(ExecutionHandler.java:167)

有问题吗?

1 个答案:

答案 0 :(得分:0)

你能尝试修改你的代码吗?

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
    //i write constructedMessage to the client;
    Channel channel = e.getChannel();
    ctx.sendDownstream(new DownstreamMessageEvent(
            channel, 
            Channels.future(channel), 
            constructMessage(e.getMessage().toString()), 
            channel.getRemoteAddress())
    );    
}