Вызов буфера протокола

Я разрабатываю приложение, которое использует буфер протокола в качестве сериализатора. Мое приложение будет клиентом для сервера. Требование состоит в том, что перед отправкой данных protobuf я должен добавить к размеру данных protobuf 4 байта. Я использую 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;
    }

}

Любая помощь поможет Спасибо.


person Arsene    schedule 08.03.2013    source источник


Ответы (2)


вам нужно объяснить немного больше о том, что не работает для вас. Если я посмотрю код в java-библиотеке protobuf RPC (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;
}

ваш сервер сетевой сервер или просто сетевой клиент?

person pjklauser    schedule 09.03.2013
comment
Я подключаюсь к серверу С#. Мне нужен декодер protobuf длиной 4 байта. - person Arsene; 12.03.2013
comment
я не эксперт по С#, но я думаю, вам нужно выяснить, каков двоичный формат длины С# int - 4 байта, со знаком или без знака, с обратным порядком байтов или с обратным порядком байтов. Затем адаптируйте клиентский Java-код для фрейма с использованием этого формата. Это может сработать, если вы используете io.netty.handler.codec.LengthFieldPrepender как FRAME_ENCODER и LengthFieldBasedFrameDecoder для FRAME_DECODER (который, возможно, нужен только серверу). - person pjklauser; 14.03.2013

Я решил проблему. Что я сделал, так это написал свой собственный кодировщик и декодер на основе данных protobuf для обмена. Основная проблема здесь заключалась в порядке следования байтов по каналу.

person Arsene    schedule 15.03.2013