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