Domanda

Durante la lettura il tutorial Netty, ho trovato un semplice descrizione di come integrare Netty e Google Protocol buffer . Ho iniziato a studiare il suo esempio (perché non vi sono ulteriori informazioni nella documentazione) e scritto una semplice applicazione come l'applicazione ora locale esempio. Ma questo esempio utilizza l'inizializzazione statica in PipeFactory classe, per esempio:.

import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;

import static org.jboss.netty.channel.Channels.pipeline;

/**
 * @author sergiizagriichuk
 */
class ProtoCommunicationClientPipeFactory implements ChannelPipelineFactory {

    public ChannelPipeline getPipeline() throws Exception {
        ChannelPipeline p = pipeline();
        p.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());
        p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance()));

        p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());
        p.addLast("protobufEncoder", new ProtobufEncoder());

        p.addLast("handler", new ProtoCommunicationClientHandler());
        return p;
    }

}

(Si prega di dare un'occhiata alla linea p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance()));) e solo una fabbrica può essere creato (se ho capito) per la classe ClientBootstrap, io metodo bootstrap.setPipelineFactory() media. Così, in questa situazione posso usare UNA messaggio da inviare al server e UNA il messaggio per ricevere dal server ed è male per me, e io non credo solo per me: (Come posso utilizzare diversi messaggi da e per un solo collegamento? Forse posso creare un paio di protobufDecoder come questo

p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance()));
p.addLast("protobufDecoder", new ProtobufDecoder(Communication.TestMessage.getDefaultInstance()));
p.addLast("protobufDecoder", new ProtobufDecoder(Communication.SrcMessage.getDefaultInstance()));

o di altre tecniche? Grazie mille.

È stato utile?

Soluzione

ho trovato filo di autore di Netty in Google Gruppi e capito che devo cambiare la mia architettura o di scrivere il mio decoder come ho scritto sopra, quindi, iniziare a pensare che modo sarà facile e migliore.

Altri suggerimenti

Se avete intenzione di scrivere i propri codec in ogni caso, si potrebbe desiderare di guardare l'implementazione dell'interfaccia Externalizable per gli oggetti di dati personalizzati.

  • Serializable è basso sforzo, ma peggiore performance (serializza tutto).
  • Protobuf è un buon compromesso tra sforzo e prestazioni (richiede Proto manutenzione)
  • Externalizable è alto sforzo, ma le migliori prestazioni (codec minimi personalizzato)

Se si conosce già il progetto dovrà scalare come una capra di montagna, si può andare alla strada difficile. Protobuf non è un proiettile d'argento.

In teoria questo può essere fatto modificando il cantiere per ogni messaggio in arrivo per soddisfare il messaggio in arrivo. Date un'occhiata alla porta unificazione esempio in Netty.

Sequenza sarebbe:
1) Nella cornice decoder o di un altro "DecoderMappingDecoder" di controllare il tipo di messaggio del messaggio in entrata
2) Modificare la tubazione in modo dinamico, come mostrato nell'esempio

Ma perché non utilizzare connessioni diverse e seguire questa sequenza:
1) Aggiungere altre decoder in cantiere sulla base del messaggio in arrivo solo una volta.
2) Aggiungere il stesso istanza di canale del gestore a monte come l'ultimo gestore in cantiere, in questo modo tutti i messaggi vengono instradati alla stessa istanza, che è quasi come avere una singola connessione.

il problema è che non v'è alcun modo per distinti due differenti messaggi protobuf una dall'altra in formato binario. Ma c'è un modo per risolverlo all'interno del file protobuf:

message AnyMessage {
    message DataMessage { [...] }
    optional DataMessage dataMessage = 1;
    message TestMessage { [...] }
    optional TestMessage testMessage = 2;
    message SrcMessage { [...] }
    optional SrcMessage srcMessage = 3;
}

campi opzionali che non sono impostati prodotti non appesantisce. Inoltre è possibile aggiungere un Enum, ma è solo un bonus.

Il problema non è piuttosto una limitazione Netty o codificatore / decodificatore limitazione. Il problema è che Google buffer protocollo stanno offrendo solo un modo per oggetti serializzare / deserializzare, ma non è fornire un protocollo. Hanno un qualche tipo di implementazione RPC come parte della distribuzione standard, ma se si tenta di attuare il loro protocollo RPC poi si ritroverà con 3 strati di indirezione. Quello che ho fatto in uno dei progetti, è stato quello di definire un messaggio che è fondamentalmente un unione di messaggi. Questo messaggio contiene un campo che è Tipo e un altro campo che è il messaggio vero e proprio. Ci si può comunque finire-up con 2 strati indirezione, ma non 3. In questo modo l'esempio dalla Netty lavorerà per voi, ma come era menzione in un post precedente, è necessario mettere più logica nel gestore logica di business.

È possibile utilizzare il messaggio tunneling per inviare diversi tipi di messaggi come payload in un unico messaggio. Speranza che aiuta

Dopo lunghe ricerche e la sofferenza ... Mi è venuta con l'idea di usare la composizione di messaggi in un unico messaggio di involucro. All'interno che l'uso messaggio che oneof per limitare il numero di oggetti consentiti per il solo uno. Checkout l'esempio:

message OneMessage {
    MessageType messageType = 1;

    oneof messageBody {
        Event event = 2;
        Request request  = 3;
        Response response = 4;
    }

    string messageCode = 5; //unique message code
    int64 timestamp = 6; //server time
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top