2013-03-08 6 views
4

프로토콜 버퍼를 serializer로 사용하는 응용 프로그램을 개발 중입니다. 내 응용 프로그램은 서버에 대한 클라이언트가됩니다. 요구 사항은 protobuf 데이터를 보내기 전에 protobuf 데이터의 크기를 4 바이트로 시작해야한다는 것입니다. 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

+0

저는 C# 전문가는 아니지만 C# int "length"의 바이너리 형식 인 4 바이트, 서명 된 또는 서명되지 않은 litte-endian 또는 big-endian을 알아야합니다. 그런 다음이 형식을 사용하여 프레임에 클라이언트 Java 코드를 적용하십시오. io.netty.handler.codec.LengthFieldPrepender를 FRAME_ENCODER로, LengthFieldBasedFrameDecoder를 FRAME_DECODER (서버 만 필요할 수도 있음)로 사용하면 효과가 있습니다. – pjklauser

0

나는이 문제를 해결했다. 내가 한 것은 protobuf 데이터를 기반으로 자신의 인코더와 디코더를 작성하여 교환하는 것입니다. 여기에서 가장 중요한 문제는 채널을 통한 바이트의 endianess였습니다.