无法将DefaultHttpResponse写入netty中的通道:“不支持的消息类型:class org.jboss.netty.handler.codec.http.DefaultHttpResponse”

时间:2013-04-03 18:24:24

标签: java netty

此特定问题与following question的可能解决方案有关。

我有两个管道,我正在接收客户端请求一个通道,然后在第二个通道上触发请求,然后将响应内容复制到新的DefaultHttpResponse,我尝试写入原始通道。但是,这会导致以下异常:

java.lang.IllegalArgumentException: unsupported message type: class org.jboss.netty.handler.codec.http.DefaultHttpResponse
at org.jboss.netty.channel.socket.nio.SocketSendBufferPool.acquire(SocketSendBufferPool.java:53)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.write0(AbstractNioWorker.java:468)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromTaskLoop(AbstractNioWorker.java:432)
at org.jboss.netty.channel.socket.nio.AbstractNioChannel$WriteTask.run(AbstractNioChannel.java:366)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processWriteTaskQueue(AbstractNioWorker.java:350)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:246)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

有谁知道为什么会这样?作为参考,这里是我的两个管道的代码(我知道我在这里做了一些线程不安全的事情,但我想在继续之前让这个用于单线程客户端):

private static Channel channel;
private static Map<Channel, Channel> proxyToClient = new ConcurrentHashMap<Channel, Channel>();

public static void main(String[] args) throws Exception {
    ChannelFactory clientFactory =
            new NioClientSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());
    final ClientBootstrap cb = new ClientBootstrap(clientFactory);
    cb.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            return Channels.pipeline(
                    new HttpRequestEncoder(),
                    new HttpResponseDecoder(),
                    new ResponseHandler());
        }
    });
    ChannelFuture cf = cb.connect(new InetSocketAddress("localhost", 18080));
    channel = cf.awaitUninterruptibly().getChannel();

    ChannelFactory factory =
            new NioServerSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());
    ServerBootstrap sb = new ServerBootstrap(factory);

    sb.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            return Channels.pipeline(
                    new HttpRequestDecoder(),
                    new RequestHandler());
        }
    });

    sb.setOption("child.tcpNoDelay", true);
    sb.setOption("child.keepAlive", true);

    sb.bind(new InetSocketAddress(2080));
}

private static class ResponseHandler extends SimpleChannelHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) {
        final HttpResponse proxyResponse = (HttpResponse) e.getMessage();
        Channel clientChannel = proxyToClient.get(e.getChannel());
        HttpResponse clientResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        clientResponse.setContent(proxyResponse.getContent());
        clientChannel.write(clientResponse).addListener(new ChannelFutureListener() {
            public void operationComplete(ChannelFuture future) {
                Channel ch = future.getChannel();
                ch.close();
            }
        });
    }
}

private static class RequestHandler extends SimpleChannelHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) {
        final HttpRequest request = (HttpRequest) e.getMessage();
        proxyToClient.put(channel, e.getChannel());
        channel.write(request);
    }
}

1 个答案:

答案 0 :(得分:2)

如何在服务器管道中添加HttpResponseEncoder?您的服务器应该知道如何将DefaultHttpResponse对象转换为字节,以便它可以通过网络发送它。