Skip to content

Associare un socket UDP (Bun.udpSocket())

Per creare un nuovo socket UDP (associato):

ts
const socket = await Bun.udpSocket({});
console.log(socket.port); // assegnato dal sistema operativo

Specifica una porta:

ts
const socket = await Bun.udpSocket({
  port: 41234, 
});

console.log(socket.port); // 41234

Inviare un datagramma

Specifica i dati da inviare, oltre alla porta e all'indirizzo di destinazione.

ts
socket.send("Hello, world!", 41234, "127.0.0.1");

Nota che l'indirizzo deve essere un indirizzo IP valido - send non esegue risoluzione DNS, poiché è destinato per operazioni a bassa latenza.

Ricevere datagrammi

Quando crei il tuo socket, aggiungi un callback per specificare cosa dovrebbe essere fatto quando i pacchetti vengono ricevuti:

ts
const server = await Bun.udpSocket({
  socket: {
    data(socket, buf, port, addr) {
      console.log(`messaggio da ${addr}:${port}:`);
      console.log(buf.toString());
    },
  },
});

const client = await Bun.udpSocket({});
client.send("Hello!", server.port, "127.0.0.1");

Connessioni

Mentre UDP non ha un concetto di connessione, molte comunicazioni UDP (specialmente come client) coinvolgono solo un peer. In tali casi può essere benefico connettere il socket a quel peer, che specifica a quale indirizzo tutti i pacchetti vengono inviati e limita i pacchetti in entrata a quel solo peer.

ts
const server = await Bun.udpSocket({
  socket: {
    data(socket, buf, port, addr) {
      console.log(`messaggio da ${addr}:${port}:`);
      console.log(buf.toString());
    },
  },
});

const client = await Bun.udpSocket({
  connect: {
    port: server.port,
    hostname: "127.0.0.1",
  },
});

client.send("Hello");

Poiché le connessioni sono implementate a livello di sistema operativo, puoi potenzialmente osservare anche benefici di prestazioni.

Inviare molti pacchetti alla volta usando sendMany()

Se vuoi inviare un grande volume di pacchetti alla volta, può avere senso raggrupparli tutti insieme per evitare l'overhead di fare una system call per ciascuno. Questo è reso possibile dall'API sendMany():

Per un socket non connesso, sendMany prende un array come unico argomento. Ogni insieme di tre elementi dell'array descrive un pacchetto: Il primo elemento è i dati da inviare, la seconda è la porta di destinazione, e l'ultimo è l'indirizzo di destinazione.

ts
const socket = await Bun.udpSocket({});

// invia 'Hello' a 127.0.0.1:41234, e 'foo' a 1.1.1.1:53 in una singola operazione
socket.sendMany(["Hello", 41234, "127.0.0.1", "foo", 53, "1.1.1.1"]);

Con un socket connesso, sendMany prende semplicemente un array, dove ogni elemento rappresenta i dati da inviare al peer.

ts
const socket = await Bun.udpSocket({
  connect: {
    port: 41234,
    hostname: "localhost",
  },
});

socket.sendMany(["foo", "bar", "baz"]);

sendMany restituisce il numero di pacchetti che sono stati inviati con successo. Come con send, sendMany prende solo indirizzi IP validi come destinazioni, poiché non esegue risoluzione DNS.

Gestire la backpressure

Può accadere che un pacchetto che stai inviando non si adatti al buffer dei pacchetti del sistema operativo. Puoi rilevare che questo è successo quando:

  • send restituisce false
  • sendMany restituisce un numero più piccolo del numero di pacchetti che hai specificato. In questo caso, il gestore socket drain verrà chiamato una volta che il socket diventa scrivibile di nuovo:
ts
const socket = await Bun.udpSocket({
  socket: {
    drain(socket) {
      // continua a inviare dati
    },
  },
});

Bun a cura di www.bunjs.com.cn