私のアイデアと、NodeJS で「ROHC」にバインディングを与えることになった経緯を紹介したいと思います。
Web-Socket 上で動作する VPN を実装したいと考えていました。利点は、サービスが HTTPS 上で隠蔽されることです。 HTTP3 を使用すると、これはさらに最適化されます。そこで、NodeJS 用の TunTap2 モジュールをいじり始めました。最初にパッチを適用する必要がありました。
常にワイヤレス テクノロジーに魅了されてきた私は、ある時点で「LoRa」とそれを使ったプロジェクト「IP2Lora」に出会いました。
画像ソース
このプロジェクト「IP2Lora」では、転送に非常に重要な 40 バイトを節約するために IP パケットが短縮されました。 434 MHz または 868 MHz の無線帯域では、それほど多くのデータを転送できません。
画像ソース
この図では、IP パケット サイズがどのように減少するかがはっきりとわかります。
残念ながら、Python のライブラリ バインディングは 1 つだけでした。
では、ノード ライブラリ バインディングを自分で書いてみませんか?
結果が表示されます。
https://www.npmjs.com/package/node-rohc
ROHC の仕組みについて詳しくは、プロジェクトへのリンクを参照するか、単に検索してください。投稿が長くなりすぎないように、ここでは説明しません。
Linux Debian/Mint にインストールしました。これは他の Linux バージョンと同様であるはずだと思います。
(ちなみに、ROHC-lib を新しいカーネルにパッチする必要もありました。)
sudo apt-get install autotools-dev sudo apt-get install automake sudo apt-get install libtool sudo apt-get install libpcap-dev sudo apt-get install -y libcmocka-dev git clone https://github.com/stefanwerfling/rohc.git cd rohc ./autogen.sh --prefix=/usr make all sudo make install
これで、プロジェクトに移動してモジュールをインストールできます。
cd yourProject npm i node-rohc
次に、NodeJS バインディングを作成する必要があります (これは、各 CPU アーキテクチャ自体に対してコンパイルする必要があります)。
cd yourProject/node_modules/node-rohc npm run build --loglevel verbose
インストールが完了しました。
次に、バイトを節約するために次のパケットに圧縮する IP パケットを取得したと仮定します。
const ipU8Packet = new Uint8Array(ipPacketBufferWithContent); console.log(ipU8Packet);
Uint8Array(52) [ 69, 0, 0, 52, 0, 0, 0, 0, 64, 6, 249, 112, 192, 168, 0, 1, 192, 168, 0, 2, 72, 101, 108, 108, 111, 44, 32, 116, 104, 105, 115, 32, 105, 115, 32, 116, 104, 101, 32, 100, 97, 116, 97, 32, 112, 97, 121, 108, 111, 97, 100, 33 ]
モジュールがインポートされ、圧縮のために IP パケットが Rhoc オブジェクトに与えられる Unit8Array がインポートされました。
import {Rohc} from 'node-rohc'; const r = new Rohc([ RohcProfiles.ROHC_PROFILE_UNCOMPRESSED, RohcProfiles.ROHC_PROFILE_IP, RohcProfiles.ROHC_PROFILE_TCP, RohcProfiles.ROHC_PROFILE_UDP, RohcProfiles.ROHC_PROFILE_ESP, RohcProfiles.ROHC_PROFILE_RTP ]); try { const compress = r.compress(ipU8Packet); console.log(compress); } catch (e) { console.error(e); }
Uint8Array(53) [ 253, 4, 69, 64, 6, 192, 168, 0, 1, 192, 168, 0, 2, 0, 64, 0, 0, 32, 0, 251, 103, 72, 101, 108, 108, 111, 44, 32, 116, 104, 105, 115, 32, 105, 115, 32, 116, 104, 101, 32, 100, 97, 116, 97, 32, 112, 97, 121, 108, 111, 97, 100, 33 ]
Rohc オブジェクトのコンストラクターで、配列内の圧縮に使用するプロファイルを指定します。
次に圧縮です。出力には新しいパッケージが表示されます。しかし、なぜもっと小さくないのでしょうか?
最初のパケットにはポート/IP アドレスなどに関する情報が含まれています。後続のパケットのみが大幅に小さくなります。
Rohc パケットを通常の IP パケットに変換するには、解凍を使用します。
try { const decompress = r.decompress(compress); console.log(decompress); } catch (e) { console.error(e); }
Uint8Array(52) [ 69, 0, 0, 52, 0, 0, 0, 0, 64, 6, 249, 112, 192, 168, 0, 1, 192, 168, 0, 2, 72, 101, 108, 108, 111, 44, 32, 116, 104, 105, 115, 32, 105, 115, 32, 116, 104, 101, 32, 100, 97, 116, 97, 32, 112, 97, 121, 108, 111, 97, 100, 33 ]
重要なのは始まりです。最初のパケットは圧縮されて宛先に送信され、宛先がパケットを解凍すると、インスタンスが維持される必要があります。そのため、接続 ID は既知のままです。これは、プログラムがオブジェクト インスタンスを実行し続ける必要があることを意味します。 2 つのページのうち 1 つ (圧縮によるソースまたは解凍による宛先) が停止した場合は、両方のページを再起動する必要があります。
役立つ情報を含む追加機能:
import {Rohc, RohcStatus} from 'node-rohc'; if (r.getLastStatus() === RohcStatus.ROHC_OK) { console.log('All OK'); }
圧縮または解凍中、ステータスは記憶されます。これを直後に再度クエリして、何が起こったのかについてのより詳細な情報を取得できます。
console.log(r.compressLastPacketInfo()); console.log(r.decompressLastPacketInfo());
{ version_major: 0, version_minor: 0, context_id: 0, is_context_init: true, context_mode: 1, context_state: 1, context_used: true, profile_id: 4, packet_type: 0, total_last_uncomp_size: 52, header_last_uncomp_size: 20, total_last_comp_size: 53, header_last_comp_size: 21 } { version_major: 0, version_minor: 0, context_mode: 2, context_state: 3, profile_id: 4, nr_lost_packets: 0, nr_misordered_packets: 0, is_duplicated: false, corrected_crc_failures: 11745388377929038000, corrected_sn_wraparounds: 14987979559889062000, corrected_wrong_sn_updates: 12105675798372346000, packet_type: 449595, total_last_comp_size: 18407961667527770000, header_last_comp_size: 1940628627783807, total_last_uncomp_size: 18407961667125117000, header_last_uncomp_size: 217316637802623 }
最後の圧縮または解凍に関する情報。
console.log(r.compressGeneralInfo()); console.log(r.decompressGeneralInfo());
{ version_major: 0, version_minor: 0, contexts_nr: 1, packets_nr: 1, uncomp_bytes_nr: 52, comp_bytes_nr: 53 } { version_major: 0, version_minor: 0, contexts_nr: 1, packets_nr: 1, comp_bytes_nr: 53, uncomp_bytes_nr: 52, corrected_crc_failures: 0, corrected_sn_wraparounds: 8518447232180027000, corrected_wrong_sn_updates: 4295000063 }
圧縮と解凍に関する一般情報。
私の小さな投稿を楽しんでいただければ幸いです。私は常に改善を歓迎します。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3