2013-03-08 206 views
4

我正在开发一个使用协议缓冲区作为序列化程序的应用程序。我的应用程序将成为服务器的客户端。要求是在发送protobuf数据之前,我必须预先设置4个字节的protobuf数据的大小。我使用Netty作为我的套接字库。我使用netty的内置协议缓冲器编码器和解码器,但我仍然没有得到正确的结果。这是我运行的代码: 管道代码协议缓冲区挑战

public class SmpPipelineFactory implements ChannelPipelineFactory { 

    private final Logger logger = LoggerFactory.getLogger(getClass()); 

    /** 
    * 
    */ 
    public SmpPipelineFactory() { 
    } 

    @Override 
    public ChannelPipeline getPipeline() throws Exception { 
     ChannelPipeline p = pipeline(); 

     // Add Decoders 
     p.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());  
     //p.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4));   
     p.addLast("protobufDecoder", new ProtobufDecoder(Pdu.getDefaultInstance())); 

     // Add encoders 
     p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender()); 
     //p.addLast("frameEncoder", new LengthFieldPrepender(4)); 
     p.addLast("protobufEncoder", new ProtobufEncoder()); 

     p.addLast("handler", new SmpChannelConnector()); 

     return p; 
    } 

} 

任何帮助将有助于 谢谢。

回答

0

你需要解释一些关于什么不适合你的东西。如果我查看protobuf RPC java库(https://code.google.com/p/protobuf-rpc-pro/)中的代码,则该类是DuplexTcpClientPipelineFactory或DuplexTcpServerPipelineFactory,它与您的代码基本相同,且“有效”。也许protobuf-rpc-pro库已经可以做你需要的东西了。

public ChannelPipeline getPipeline() throws Exception { 
    ChannelPipeline p = pipeline(); 

    RpcSSLContext ssl = bootstrap.getSslContext(); 
    if (ssl != null) { 
      p.addLast(Handler.SSL, new SslHandler(ssl.createClientEngine())); 
    } 

    p.addLast(Handler.FRAME_DECODER, new ProtobufVarint32FrameDecoder()); 
    p.addLast(Handler.PROTOBUF_DECODER, new ProtobufDecoder(DuplexProtocol.WirePayload.getDefaultInstance(),bootstrap.getExtensionRegistry())); 

    p.addLast(Handler.FRAME_ENCODER, new ProtobufVarint32LengthFieldPrepender()); 
    p.addLast(Handler.PROTOBUF_ENCODER, new ProtobufEncoder()); 

    // the connectResponseHandler is swapped after the client connection 
    // handshake with the RpcClient for the Channel 
    p.addLast(Handler.CLIENT_CONNECT, new ClientConnectResponseHandler()); 

    return p; 
} 

是你的服务器的netty服务器,或只是一个netty客户端?

+0

我正在连接到C#服务器。我需要一个4字节长度的protobuf解码器。 – Arsene 2013-03-12 11:08:45

+0

我不是C#专家 - 但我想你需要找出什么是C#int“长度”的二进制格式 - 4字节,有符号或无符号,litte-endian或big-endian。然后使用这种格式将客户端java代码调整为帧。如果对FRAME_DECODER(可能只有服务器需要)使用io.netty.handler.codec.LengthFieldPrepender作为FRAME_ENCODER和LengthFieldBasedFrameDecoder,它可能会正常工作。 – pjklauser 2013-03-13 20:23:33

0

我已经解决了这个问题。我所做的是根据要交换的protobuf数据编写我自己的编码器和解码器。这里的主要问题是通道上的字节的永久性。