かなり痛そうですね。私は通常のnettyユーザーですが、少なくとも、あなたが説明したように、Nettyでこのようなプロトコルを実装することはありません(nettyに反対するものではありませんが、他の場所で実装されています)。この道を進む前に、概説したすべてのトランスポート機能を備えた「信頼性の高いUDP」スタックを実装したJGroupsを見てみましょう。
これを最初に刺したのは(無人島にいた場合)、次のようになります。
下流
sendMessage
--> MessageSplitHandler
--> MessageFragmentBufferHandler
RetransmitRequester -->
どこ:
- MessageSplitHandlerは、送信されたメッセージをUDPに適したサイズのMessageFragments(データグラム)に分割します(元のメッセージが十分に小さい場合は、そのうちの1つが存在する可能性があります)。親メッセージから作成されたMessageFragmentごとに、以下を割り当てます。
- 親メッセージの一意のID。
- シーケンス番号
- オリジナルから作成されたフラグメントの総数
- MessageFragmentBufferHandlerは、リモートエンドがメッセージの受信を確認するまで(または、メッセージの再アセンブリをタイムアウトして未確認のメッセージを破棄することを選択するまで)、各MessageFragmentを格納します。それ以外の場合は、リモート要求がMessageFragmentを再送信する場合に備えて(おそらくparent-message-idとフラグメントシーケンスによって)それらを保持します。
上流の
これは多かれ少なかれ下流の逆になります。
MessageFragmentDecoder <--
MessageFragmentBuffer <--
MessageReAssember <--
onMessage
- MessageFragmentDecoder:データグラムをMessageFragmentにデコードします。
- MessageFragmentBuffer:すべてのシーケンスが受信されるまで、MessageFragmentsの配列を格納します。メッセージが順不同で受信された場合は、中間体が失われたと想定し、送信者にメッセージを再送信するように依頼します(unique-id / sequenceによる)
- MessageReAssember:すべてのMessageFragmentsが受信されると、この男は元のメッセージを再構成し、それをメッセージ受信者に渡します。
それが一般的な考え方だと思いますが、おそらくそこには200〜300のコーナーケースがあります。