ポート統合の例をコードベースに適応させようとしています。私が抱えていると思う問題は、サーバーがシャットダウンするか、クライアントがタスクを完了するまで、またはより具体的には、同じパイプラインがずっと使用されるまで、クライアントとサーバーの間でチャネルが開いたままになることです。そのため、統合ハンドラがパイプラインから削除された例のワークフローは機能しません。
ポート統合の例で見た問題は、クライアントが各リクエストの前に保留中のマジック バイトを保持し続けていたが、サーバー側のチャネルがポート統合ハンドラーを削除したことでした。有効なプロトコル メッセージであること。クライアントからのプレフィックス マジック バイトを含むチャネルを介した後続のメッセージは、統合ハンドラがパイプラインでマジック バイトを消費しなくなったため、処理できず、メッセージの形式が正しくありませんでした。
統合ハンドラーをパイプラインに残すことでこれを回避できましたが、スニファーがプロトコルを識別するたびに、プロトコル ハンドラーが追加されていました。パイプラインはチャネルの存続期間中永続的だったので、同じハンドラーを何度も追加し続けました。これは、チャネルに属性を追加してパイプラインに再度追加することを回避することで簡単に回避できました。
今私が見ている問題は、メッセージがいくつかのバッファに分割されていることです。クライアントが 2k バイトを 2 つのメッセージに分割して送信した場合。最初のメッセージは正しく盗聴され、次のハンドラー (具体的には、LengthFieldBasedFrameDecoder) に渡されます。すべてのバイトが揃っているわけではないので、残りを待ちます。次のメッセージが残りのバイトと共に入ってくると、パイプラインから統合子を削除できないため、もう一度スニッフィングしますが、スニッフィングは失敗します。
これに対する回避策、または同じことを達成するためのより良い方法はありますか?
アップデート:
ユニファイアからマジック バイトの消費を移動することは正しいアプローチのように思えますが、まだ問題になっている (またはそう思われる) のは、パイプラインを動的に変更することが netty 4 では netty と同じように機能しないことです。 3.
私のクライアントプロトコルは、それを識別するためにバイトシーケンスを使用してすべてのリクエストを先頭に追加しています。netty 3 では、単純に ChannelBuffer 内のバイトをスキップし、ユニファイヤを削除して、その要求を処理するための適切なプロトコル処理を追加しました。後続のすべてのリクエストで同じことが起こり、完全に機能しました。
ただし、netty 4 では、マジック バイトを消費するパイプラインからハンドラーを削除すると、クライアントがチャネルを閉じるまで存続するチャネルの存続期間中、そのハンドラーはなくなります。したがって、チャネルを通過する各メッセージに対してパイプライン/ChannelHandlerContext が新しいように見える前は、毎回再利用されており、これが問題の場所だと思います。
事実、これにより、この種のパイプラインの動的な変更は、実際には困難または不可能になります。各リクエストの最初の N バイトだけを消費する何かが欲しいのですが、いくつかの ByteBuf に分割された大きなリクエストはすべて最初の N バイトを食べてしまうため、パイプラインに残すことはできません。
更新 2: 現在見ている動作は、フォローアップ トピックで言及した内容に関連していると思います: プロトコルを識別するプレフィックス付きバイト シーケンスを管理する方法