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.
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.
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.
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
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.
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:
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.
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.
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.
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!