Question

Pendant la lecture du tutoriel Netty, je l'ai trouvé simple Description de la façon d'intégrer Netty et Google Protocole buffers. J'ai commencé à étudier son exemple (parce qu'il n'y a pas plus d'informations dans la documentation) et écrit une simple application comme l'exemple d'application de l'heure locale. Mais cet exemple utilise l'initialisation de la statique dans PipeFactory classe, par exemple:.

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;
    }

}

(S'il vous plaît jeter un oeil à la ligne p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance()));) et juste une usine peut être créé (que je comprends) pour la classe de ClientBootstrap, je veux dire la méthode de bootstrap.setPipelineFactory(). Ainsi, dans cette situation, je peux utiliser UN message à envoyer au serveur et ONE message à recevoir du serveur et il est mauvais pour moi, et je pense pas seulement pour moi: (Comment puis-je utiliser différents messages depuis et vers pour une seule connexion? Je pourrais peut-être créer quelques protobufDecoder comme ceci

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

ou d'autres techniques? Merci beaucoup.

Était-ce utile?

La solution

Je l'ai trouvé fil de l'auteur de Netty dans groupes google et compris que je dois changer mon architecture ou écrire mon propre décodeur comme je l'ai écrit plus haut, donc, commencer à penser de quelle façon sera facile et mieux.

Autres conseils

Si vous allez écrire vos propres codecs de toute façon, vous voudrez peut-être regarder la mise en œuvre de l'interface Externalizable pour les objets de données personnalisées.

  • Serializable est faible effort, mais plus mauvaise performance (sérialise tout).
  • Protobuf est un bon compromis entre l'effort et la performance (nécessite l'entretien .proto)
  • Externalizable est un effort important, mais la meilleure performance (codecs personnalisés minimum)

Si vous connaissez déjà votre projet aura à l'échelle comme une chèvre de montagne, vous pouvez avoir à aller la route dure. Protobuf n'est pas une balle d'argent.

Théoriquement, cela peut se faire en modifiant le pipeline pour chaque message entrant en fonction du message entrant. Jetez un oeil à l'unification du port exemple Netty.

Séquence serait:
1) Dans un décodeur de cadre ou d'une autre « DecoderMappingDecoder » vous vérifiez le type du message entrant de message
2) Modification du pipeline de façon dynamique, comme indiqué dans l'exemple

Mais pourquoi ne pas utiliser des connexions différentes et suivez cette séquence:
1) Ajouter d'autres décodeurs dans la canalisation en fonction du message entrant une seule fois.
2) Ajouter même instance de gestionnaire en amont du canal comme le dernier gestionnaire dans le pipeline, de cette façon tous les messages sont acheminés vers la même instance, qui est presque comme avoir une seule connexion.

le problème est qu'il n'y a aucun moyen de deux messages distincts de protobuf différents les uns des autres au format binaire. Mais il y a un moyen de le résoudre dans le fichier protobuf:

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

champs facultatifs qui ne figurent pas produit pas de frais généraux. En outre, vous pouvez ajouter un Enum, mais il est juste un bonus.

La question est pas tout à fait une limitation Netty ou encodeur / décodeur limitation. Le problème est que Google Protocol Buffers offrent simplement un moyen d'objets linéariser / délinéariser, mais est fournit pas un protocole. Ils ont une sorte de mise en œuvre RPC dans le cadre de la distribution standard, mais si vous essayez de mettre en œuvre leur protocole RPC, vous vous retrouverez avec 3 couches de indirection. Ce que je l'ai fait dans l'un du projet, était de définir un message qui est essentiellement une union des messages. Ce message contient un champ qui est le type et un autre champ qui est le message réel. Vous finirez-up toujours avec 2 couches de indirection, mais pas 3. De cette manière, l'exemple de Netty travaillera pour vous, mais comme cela a été mentionné dans un précédent post, vous devez mettre plus logique dans le gestionnaire de logique métier.

Vous pouvez utiliser un tunnel de messagerie pour envoyer différents types de messages comme charge utile dans un seul message. Hope qui aide

Après de longues recherches et de la souffrance ... Je suis venu avec l'idée d'utiliser la composition des messages dans un message d'emballage. A l'intérieur que l'utilisation message I oneOf pour limiter le nombre d'objets autorisés à la une seule. Checkout l'exemple:

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
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top