2017-11-15 11 views
1

マイチャンネルのパイプラインにはいくつかのデコーダが含まれています。これらのデコーダはすべてTextWebSocketFrameメッセージで動作します。今私の問題は、私はメッセージのいくつかのコンテンツに適切なデコーダベースを選択する必要があるということです。nettyデコーダ内のメッセージをパイプラインの次のハンドラ/デコーダに送るには?

本質的に、メッセージの特定のフィールドを解析し、メッセージの処理を続行するか、メッセージを次のエンコーダ/ハンドラに渡す必要があるかどうかを判断する必要があります。

ほとんどの人は、このような場合にすべてのメッセージをデコードすることを推奨しますが、一部のデコーダが動的に追加され、すべてのロジックを1つのデコーダに入れるのは難しいでしょう。

は、現在のコードは次のようになります。

@Override 
protected void decode(ChannelHandlerContext ctx, TextWebSocketFrame msg, List<Object> out) throws Exception { 
    String messageAsJson = msg.text(); 
    JsonObject jsonObject = JSON_PARSER.fromJson(messageAsJson, JsonObject.class); 

    JsonObject messageHeader = jsonObject.getAsJsonObject(MESSAGE_HEADER_FIELD); 
    String serviceAsString = messageHeader.get(MESSAGE_SERVICE_FIELD).getAsString(); 
    String inboundTypeAsString = messageHeader.get(MESSAGE_TYPE_FIELD).getAsString(); 

    Service service = JSON_PARSER.fromJson(serviceAsString, Service.class); 
    InboundType inboundType = JSON_PARSER.fromJson(inboundTypeAsString, InboundType.class); 

    if (service == Service.STREAMING) { 
     out.add(decodeQuotesMessage(inboundType, messageAsJson)); 
    } else { 

    } 
} 

だから基本的に私は、パイプラインの次のハンドラにメッセージを渡すために、他の枝にいくつかのロジックを必要とするだろう。

このアプローチは最も効率的な方法ではありませんが、私のサービスのアーキテクチャは、このロジックと高速パスを含む低速パス(別のスレッドプール上で実行されます)を持っています。したがって、私はこの場所でいくつかの遅いコードを受け入れることができます。一般的に

答えて

0

、あなたはこのようなものが必要です。

if (service == Service.STREAMING) { 
    ctx.pipeline().addLast(new StreamingHandler()); 
} else { 
    ctx.pipeline().addLast(new OtherHandler()); 
} 
out.add(decodeQuotesMessage(inboundType, messageAsJson)); 
ctx.pipeline().remove(this); 

を背後にあるロジックは次です:

  1. あなたはヘッダをデコードし、あなたがに従う必要が流れ、今何を知っています。
  2. ヘッダに応じて特定のハンドラをパイプラインに追加します。
  3. 「out」リストにデコードされたメッセージを追加すると、「このデコードされたメッセージをパイプラインの次のハンドラに送ります。つまり、現在のハンドラがパイプラインの最後にある場合はステップ2で定義されたハンドラです。
  4. プロトコルが同じヘッダーを何度も送信する場合に備えて、ハンドラの重複を避けるために、現在のハンドラをパイプラインから削除します。しかし、これはあなたのプロトコルに特有のステップであり、必要でないかもしれません。

これは単なる一般的なアプローチですが、実際はプロトコルの流れに依存します。

関連する問題