いくつかの異なるクラスの意図を理解していないと思います。
したがって、単純なパイプラインがあります。基本的には、カスタム メソッド (hadoop writables) を介してシリアル化する最上位オブジェクトを取得し、これらを ByteBuf に変換して送信しようとします。そこで、メッセージ オブジェクトを受け取る OutboundFrameHandler を実装し、単純なフレーミングをシリアル化して上流に送信しようとしました。実装は次のとおりです。
public class OutboundFrameHandler extends MessageToByteEncoder<MsgType> {
public void encode(ChannelHandlerContext ctx, MsgType msg, ByteBuf out) throw Exception {
byte[] data = ...; // custom serialization mechanism
out.writeInt(data.length + 4);
out.writeInt(msg.callId);
out.writeBytes(data);
}
}
実行時に私はこれを取得します:
警告: exceptionCaught() イベントが発生し、パイプラインの最後に到達しました。これは通常、パイプラインの最後の受信ハンドラーが例外を処理しなかったことを意味します。io.netty.channel.NoSuchBufferException: 適切な宛先バッファーが見つかりませんでした。パイプラインが正しく構成され、そのハンドラーが期待どおりに動作するかどうかを再確認してください。
ソース コードの例を見たところ、「エンコーディング」コーデックが次のようになっていることに気付きました。 public class StringEncoder extends MessageToMessageEncoder {}
'encode' メソッドは ByteBuf を作成します。
しかし、ProtobufVarint32LengthFieldPrepender が MessageToByteEncoder を拡張し、ByteBuf out 引数を使用していることにも気付きました。ソースコードを見ましたが、「out」がどのように設定されるのかよくわかりません。ctx.nextOutboundByteBuffer() を呼び出すことによって MessageToByteEncoder の「フラッシュ」で取得されますが、これがどのように機能しているかは明確ではありません。これがどのように発生するかを見ると、これは init 中に設定され、ハンドラーの 1 つが newOutboundBuffer から ByteBuf を返す必要があるようです。
後方分析を行うと、newOutboundBuffer() から ByteBuf を返す唯一のサブクラスは ChannelOutboundByteHandlerAdapter のようです。そして、そのサブクラスはほとんどありません。
そのため、 localtimeの例を見ると、 ProtobufVarin32LengthFieldPrepender が実際にどのように動作するかは明確ではありません。また、私が MessageToByteEncoder を使用していたときに、本当に欲しいのは MessageToMessageEncoder であるようです
要約の質問: - MessageToByteEncoder をいつ使用するか - パイプライン内のハンドラーが newOutboundBuffer から ByteBuf を返さないように見える場合、MessageToByteEncoder に基づくエンコーダーはどのように有効なアウトバウンド buf を取得しますか?
**自分自身に答える**
(a) 正しいメッセージ タイプをキューに入れていなかったことが判明しました。(b)「最後の手段」のByteBufジェネレーターであるHeadHandlerについて知りました。今はすべて順調です。