Skip to content

Bind de um socket UDP (Bun.udpSocket()) ​

Para criar um novo socket UDP (bound):

ts
const socket = await Bun.udpSocket({});
console.log(socket.port); // atribuído pelo sistema operacional

Especifique uma porta:

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

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

Enviar um datagrama ​

Especifique os dados para enviar, assim como a porta de destino e endereço.

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

Note que o endereço deve ser um endereço IP válido - send não realiza resolução DNS, pois é destinado a operações de baixa latência.

Receber datagramas ​

Ao criar seu socket, adicione um callback para especificar o que deve ser feito quando pacotes forem recebidos:

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

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

Conexões ​

Embora UDP não tenha um conceito de conexão, muitas comunicações UDP (especialmente como cliente) envolvem apenas um peer. Em tais casos, pode ser benéfico conectar o socket àquele peer, o que especifica para qual endereço todos os pacotes são enviados e restringe pacotes de entrada apenas àquele peer.

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

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

client.send("Hello");

Como conexões são implementadas no nível do sistema operacional, você pode potencialmente observar benefícios de performance também.

Enviar muitos pacotes de uma vez usando sendMany() ​

Se você quer enviar um grande volume de pacotes de uma vez, pode fazer sentido agrupá-los todos juntos para evitar o overhead de fazer uma system call para cada um. Isto é tornado possível pela API sendMany():

Para um socket não conectado, sendMany recebe um array como único argumento. Cada conjunto de três elementos do array descreve um pacote: O primeiro item são os dados a serem enviados, o segundo é a porta alvo, e o último é o endereço alvo.

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

// envia 'Hello' para 127.0.0.1:41234, e 'foo' para 1.1.1.1:53 em uma única operação
socket.sendMany(["Hello", 41234, "127.0.0.1", "foo", 53, "1.1.1.1"]);

Com um socket conectado, sendMany simplesmente recebe um array, onde cada elemento representa os dados a serem enviados ao peer.

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

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

sendMany retorna o número de pacotes que foram enviados com sucesso. Assim como send, sendMany apenas recebe endereços IP válidos como destinos, pois não realiza resolução DNS.

Lidar com backpressure ​

Pode acontecer que um pacote que você está enviando não cabe no buffer de pacotes do sistema operacional. Você pode detectar que isto aconteceu quando:

  • send retorna false
  • sendMany retorna um número menor que o número de pacotes que você especificou. Neste caso, o handler de socket drain será chamado uma vez que o socket se torne gravável novamente:
ts
const socket = await Bun.udpSocket({
  socket: {
    drain(socket) {
      // continua enviando dados
    },
  },
});

Bun by www.bunjs.com.cn edit