質問

Netty チュートリアルを読んでいると、簡単な方法を見つけました。 説明 Netty を統合する方法と Google プロトコル バッファー. 。私はその例を調査し始め (ドキュメントにこれ以上の情報がないため)、サンプルの現地時間アプリケーションのような単純なアプリケーションを作成しました。ただし、この例では PipeFactory クラスで静的初期化を使用しています。例:

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

}

(ラインを見てください p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance()));)そして、(私が理解しているように)1つの工場だけを作成できます ClientBootstrap クラス、つまり bootstrap.setPipelineFactory() 方法。したがって、この状況では使用できます 1つ サーバーに送信するメッセージと 1つ サーバーからメッセージを受信するのですが、それは私にとって悪いことであり、私だけではないと思います:( 1つの接続で送受信する異なるメッセージを使用するにはどうすればよいですか?もしかしたらいくつか作れるかも知れません protobufDecoder このような

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

それとも他のテクニック?どうもありがとう。

役に立ちましたか?

解決

Netty Inの著者のスレッドを見つけました Googleグループ そして、上に書いたようにアーキテクチャを変更したり、自分のデコーダーを書いたりしなければならないことを理解していたので、どんな方法が簡単かつ良くなるかを考え始めてください。

他のヒント

とにかく独自のコーデックを書く場合は、カスタムデータオブジェクトの外部化可能なインターフェイスを実装することを検討することをお勧めします。

  • Serializableは低エフォルトですが、最悪のパフォーマンス(すべてをシリアル化)します。
  • Protobufは、努力とパフォーマンスの間の良いトレードオフです(プロトメンテナンスが必要です)
  • 外部化可能は高い努力ですが、最高のパフォーマンス(カスタムミニマルコーデック)

あなたのプロジェクトが山のヤギのようにスケーリングする必要があることをすでに知っているなら、あなたは困難な道を行く必要があるかもしれません。 Protobufは銀の弾丸ではありません。

理論的には、これは、着信メッセージに合わせて入ってくる各メッセージのパイプラインを変更することで実行できます。を見てください ポート統一 Nettyの例。

シーケンスは次のとおりです。
1)フレームデコーダーまたは別の「deCodermappingDecoder」で、受信メッセージのメッセージタイプを確認します
2)例に示すように、パイプラインを動的に変更する

ただし、別の接続を使用して、このシーケンスに従ってみませんか。
1)着信メッセージに基づいて、パイプラインに他のデコーダーを1回だけ追加します。
2)追加します 同じ チャンネルアップストリームハンドラーのインスタンスパイプラインの最後のハンドラーとして、この方法ですべてのメッセージが同じインスタンスにルーティングされます。これは、単一の接続があるようなものです。

問題は、バイナリ形式で2つの異なるプロトブフメッセージを区別する方法がないことです。しかし、Protobufファイル内でそれを解決する方法があります。

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

設定されていないオプションのフィールドは、頭上では生成されません。さらに、列挙を追加できますが、それは単なるボーナスです。

この問題は、Netty の制限やエンコーダ/デコーダの制限とはまったく異なります。問題は、Google プロトコル バッファーがオブジェクトをシリアル化/逆シリアル化する方法を提供しているだけで、プロトコルを提供していないことです。標準ディストリビューションの一部として、ある種の RPC 実装が用意されていますが、RPC プロトコルを実装しようとすると、最終的に 3 つの間接層が必要になります。プロジェクトの 1 つで私が行ったことは、基本的にメッセージの結合であるメッセージを定義することでした。このメッセージには、タイプであるフィールドが 1 つと、実際のメッセージであるフィールドが 1 つ含まれています。最終的には間接層は 2 つになりますが、3 つにはなりません。このように、Netty の例はうまく機能しますが、前の投稿で述べたように、ビジネス ロジック ハンドラーにさらにロジックを追加する必要があります。

メッセージトンネリングを使用して、さまざまなタイプのメッセージを1つのメッセージでペイロードとして送信できます。それが役立つことを願っています

長い研究と苦しみの後...私はメッセージの構成を1つのラッパーメッセージに使用するというアイデアを思いつきました。そのメッセージの中で私が使用します の一つ 許可されたオブジェクトの数を制限するキー 唯一。例を確認してください:

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
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top