Heim  >  Artikel  >  Web-Frontend  >  NodeJS + ROHC

NodeJS + ROHC

WBOY
WBOYOriginal
2024-07-31 07:05:33535Durchsuche

Von der Idee bis zur Umsetzung

Ich möchte Ihnen meine Idee vorstellen und wie es dazu kam, „ROHC“ eine Bindung in NodeJS zu geben.

Ich wollte ein VPN implementieren, das über Web-Socket läuft. Die Vorteile wären, dass der Dienst über HTTPS verborgen wäre. Mit HTTP3 wäre dies noch optimierter. Also fing ich an, mit dem TunTap2-Modul für NodeJS herumzuspielen, das ich zuerst patchen musste.

Schon immer fasziniert von drahtloser Technologie, bin ich irgendwann auf „LoRa“ und damit auf ein Projekt „IP2Lora“ gestoßen.

Image description

Bildquelle

In diesem Projekt „IP2Lora“ wurden die IP-Pakete gekürzt, um 40 Bytes einzusparen, was für die Übertragung sehr wichtig ist; mit einem Funkband von 434 MHz oder 868 MHz kann nicht so viel übertragen werden.

NodeJS + ROHC

Bildquelle

In der Grafik ist deutlich zu erkennen, wie die IP-Paketgröße abnimmt.

Leider gab es nur eine lib-Bindung für Python.

Warum also nicht selbst eine Knotenbibliotheksbindung schreiben!?

Das Ergebnis ist nun sichtbar.
https://www.npmjs.com/package/node-rohc

Mehr über die Funktionsweise von ROHC erfahren Sie in den Links zum Projekt oder suchen Sie einfach danach. Ich werde es hier nicht erklären, um den Beitrag nicht zu lang zu machen.

Installationsbibliothek

Ich habe unter Linux Debian/Mint installiert. Ich denke, das sollte ähnlich wie bei anderen Linux-Versionen sein.

(Übrigens musste ich auch die ROHC-lib auf den neuen Kernel patchen.)

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

NPM-Installation

Jetzt können wir in unser Projekt gehen und das Modul installieren.

cd yourProject
npm i node-rohc

Jetzt müssen wir die NodeJS-Bindung erstellen (diese muss für jede CPU-Architektur selbst kompiliert werden).

cd yourProject/node_modules/node-rohc
npm run build --loglevel verbose

Die Installation ist nun abgeschlossen.

Codierung/API-Nutzung

Nehmen wir nun an, wir erhalten ein IP-Paket, das wir in die folgenden Pakete komprimieren möchten, um Bytes zu sparen.

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
]

Das Modul wird nun importiert und das Unit8Array, in dem das IP-Paket zur Komprimierung an das Rhoc-Objekt übergeben wird.

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
]

Im Konstruktor des Rohc-Objekts geben wir die Profile an, die zur Komprimierung in einem Array verwendet werden sollen.

Dann kommt die Komprimierung. In der Ausgabe sehen wir das neue Paket. Aber warum ist es nicht kleiner?

Das erste Paket enthält noch die Informationen zu Port/IP-Adresse usw. Nur die folgenden Pakete werden deutlich kleiner.

Um das Rohc-Paket wieder in ein normales IP-Paket umzuwandeln, verwenden wir Dekomprimierung.

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
]

Wichtig ist der Anfang, das erste Paket wird komprimiert und an das Ziel übertragen und das Ziel hat das Paket dekomprimiert, die Instanz muss beibehalten werden. Damit die Verbindungs-ID bekannt bleibt. Das bedeutet, dass das Programm die Objektinstanz am Laufen halten muss. Wenn eine der beiden Seiten (Quelle mit Komprimierung oder Ziel mit Dekomprimierung) gestoppt wird, müssen beide Seiten neu gestartet werden.

Zusätzliche Funktion mit nützlichen Informationen:

Letzter Komprimierungs-/Dekomprimierungsstatus

import {Rohc, RohcStatus} from 'node-rohc';

    if (r.getLastStatus() === RohcStatus.ROHC_OK) {
      console.log('All OK');
    }

Während der Komprimierung oder Dekomprimierung wird der Status gespeichert; Dies kann direkt im Anschluss noch einmal abgefragt werden, um genauere Informationen zum Geschehen zu erhalten.

Letzte Informationen zum Komprimieren/Dekomprimieren des Pakets

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
}

Informationen zur letzten Komprimierung oder Dekomprimierung.

Allgemeine Komprimierungs-/Dekomprimierungsinformationen

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
}

Allgemeine Informationen zur Komprimierung und Dekomprimierung.

Letztes Wort

Ich hoffe, Ihnen hat mein kleiner Beitrag gefallen. Ich bin immer offen für Verbesserungen.

Das obige ist der detaillierte Inhalt vonNodeJS + ROHC. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn