Netty:如何在不制作数据副本的情况下通过HTTP发送protobuf?

时间:2014-06-24 18:44:11

标签: java netty

我正在编写一个Netty HTTP客户端,通过Haproxy负载均衡器将protobuf数据发送到Netty HTTP服务器。

我尝试使用HttpPostRequestEncoder添加一个body属性,但是我担心要制作多个数据副本,因为我必须将Protobuf转换为字符串。

是否可以使用HTTP直接发送二进制数据(指定内容类型)?数据量是可变的。

这是我的客户端管道 -

    @Override
    protected ChannelHandler addDecoder() {
        return null;
    }

    @Override
    protected ChannelHandler addEncoder() {
        return new HttpClientCodec();
    }

    @Override
    protected ChannelHandler addMessageHandler() {
        return new HttpResponseHandler();
    }

    @Override
    protected PipelineSslContext addSslContext() {
        return null;
    }

    @Override
    protected List<ChannelHandler> addSecondaryDecoders() {
        return null;
    }

    @Override
    protected List<ChannelHandler> addSecondaryEncoders() {
        List<ChannelHandler> encoders = new ArrayList<>();
        encoders.add(new ChunkedWriteHandler());
        return encoders;
    }

这就是我发送数据的方式 -

    //Message is a proto message. Ideally this could have been done with a custom ProtoToHttpRequest encoder 
    //but it doesn't seem to work.
    // This is also doing a data copy
    String data = Base64.encodeBase64String(message.toByteArray());
    //String data = new String(message.toByteArray());

    HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, httpUri);
    if (headerField != null) {
        Object value = message.getField(headerField);
        if (value != null) {
            request.headers().set(HttpHeaders.Names.COOKIE, ClientCookieEncoder.encode(
                    new DefaultCookie("SESSIONID", (String) value)));
        }
    }

    request.headers().set(HttpHeaders.Names.HOST, m_endPoint.getHost());
    request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
    HttpPostRequestEncoder bodyRequestEncoder = new HttpPostRequestEncoder(factory, request, false);
    bodyRequestEncoder.addBodyAttribute("message", data);
    request = bodyRequestEncoder.finalizeRequest();
    socket.write(request);
    if (bodyRequestEncoder.isChunked()) {
        socket.writeAndFlush(bodyRequestEncoder);
    }
    else
        socket.flush();

0 个答案:

没有答案