Saat Anda perlu mengirimkan data melalui UDP, Anda menghadapi keterbatasannya: data harus dikirim dalam potongan kecil agar sesuai dengan MTU, paket bisa hilang tanpa pemberitahuan, terduplikasi, atau dalam urutan yang salah.
uTP (protokol transport mikro) ditemukan oleh orang-orang torrent untuk mengirimkan file dengan aman melalui UDP. Pada dasarnya, ia menambahkan fitur TCP ke UDP: paket yang hilang dikirim ulang secara otomatis, pesanan dijamin, duplikat ditolak.
Pustaka ini mengimplementasikan uTP melalui UDP sehingga ketika terhubung Anda menerima objek soket yang berperilaku seperti soket tcp Node.js. Ia memancarkan 'data' saat menerima data, ia memiliki metode .write() bagi Anda untuk mengirim Buffer. Sama seperti soket TCP, ini adalah aliran Node.js.
Namun, pustaka tersebut mungkin tidak kompatibel dengan implementasi uTP lainnya (jadi Anda perlu menggunakan pustaka yang sama pada kedua rekannya) karena pustaka tersebut menambahkan fitur berikut: instance kelas yang sama dapat digunakan baik sebagai server maupun sebagai server. klien secara bersamaan pada port yang sama. Jadi Anda dapat membuat Node, mengikatnya ke port dan pada saat yang sama mulai mendengarkan koneksi masuk dan juga membuat koneksi keluar darinya.
npm install --save utp-punch
const Node = require('utp-punch');
let server = new Node(socket => {
console.log('server: socket connected');
socket.on('data', data => {
console.log(`server: received '${data.toString()}'`);
socket.write('world');
socket.end();
});
socket.on('end', () => {
console.log('server: socket disconnected');
server.close(); // this is how you terminate node
});
});
server.bind(20000, '127.0.0.1'); // bind to port 20000
server.listen( // run
() => console.log('server: ready')
);
let client = new Node();
client.bind(); // bind to any port
client.connect(20000, '127.0.0.1', socket => {
console.log('client: socket connected');
socket.on('data', data => console.log(`client: received '${data.toString()}'`));
socket.on('end', () => {
console.log('client: socket disconnected');
client.close(); // this is how you terminate node
});
socket.write('hello');
});
Teknik lain yang digunakan di sini adalah pelubangan UDP.
Ketika server dan/atau klien berada di belakang NAT, mereka biasanya tidak memiliki alamat IP Internet untuk diikat agar dapat menerima koneksi masuk.
Pelubangan UDP menipu firewall agar membuka lubang sementara bagi penggunanya, sehingga port pada perangkat NAT menjadi terikat ke port server/klien di dalam LAN.
Agar dapat berfungsi, baik server maupun klien harus menggunakan server pihak ketiga untuk mengetahui alamat IP NATed masing-masing dan untuk mengoordinasikan upaya pelubangan (harus dilakukan secara bersamaan di server dan di klien).
Namun ketika koneksi dibuat, server pihak ketiga tidak lagi diperlukan dan tidak pernah digunakan sebagai relay, semua data dikirimkan secara langsung antara server NATed ini dan klien.
const Node = require('utp-punch');
let server = new Node();
server.bind(20000);
let client = new Node();
client.bind(30000); // client needs dedicated port
// just as the server
// both server and client must contact a third party server
// which will report their peer NATed address and port to them
let serverAddress, serverPort;
let clientAddress, clientPort;
// up to ten punches:
server.punch(10, clientPort, clientAddress, success => {
// if success is true hole is punched from our side
// nothing to do here as the client will try
// to connect normally when he is also successful
});
client.punch(10, serverPort, serverAddress, success => {
if (success) {
client.connect(serverPort, serverAddress, socket => {
// if the server had also been successful in punching
// this will succeed
});
client.on('timeout', () => {
// if the server had failed in punching we won't be
// able to connect
});
}
});
Silakan lihat contoh pelubangan lengkap di direktori contoh/ .
Kelas yang sama dapat digunakan sebagai server atau klien, sintaksnya adalah sebagai berikut:
pilihannya adalah sebagai berikut:
{
bufferSize: 64, // number of packets
mtu: 1000, // bytes excluding uTP header
timeout: 5000, // ms
resend: 100, // ms
keepAlive: 1000, // ms
}
onConnection akan meneruskan satu argumen - soket. Ini adalah koneksi masuk server
Pengambil jumlah koneksi maksimum yang dapat ditangani oleh Node
Pengambil untuk jumlah koneksi masuk
Pengambil untuk jumlah koneksi keluar
Mengembalikan soket UDP Node.js standar yang digunakan di bawah tenda.
Alamat terikat soket (sama seperti di Node.js UDP .address())
Ikat ke host:port dan jalankan onBound setelah selesai
Mulailah memasukkan upaya ke host:port dan jalankan panggilan balik ketika upaya berhasil atau tidak ada lagi. Keberhasilan atau kegagalan diteruskan ke callback sebagai parameter boolean pertama
Ubah Node ini menjadi server dan jalankan panggilan balik ini ketika siap menerima koneksi masuk
Hubungkan ke server Node di host:port dan jalankan panggilan balik dengan objek soket sebagai parameter tunggal
Hentikan semua koneksi dan Node, jalankan panggilan balik.
Objek soket yang diteruskan ke konstruktor Node dan panggilan balik .connect() adalah aliran yang memancarkan 'data' saat menerima data. Ia memiliki metode yang biasa: .write(), .end(), dll.
Pustaka 'utp' asli dibuat oleh @mafintosh di https://github.com/mafintosh/utp. Ini adalah penulisan ulang dalam JavaScript modern dengan perbaikan bug dan fitur tambahan termasuk penggunaan sebagai server dan klien secara bersamaan pada port yang sama dan dukungan pelubangan UDP.