Skip to content

Commit

Permalink
add docs for UDP (#10562)
Browse files Browse the repository at this point in the history
Co-authored-by: Georgijs Vilums <=>
  • Loading branch information
gvilums authored Apr 27, 2024
1 parent 9416ee4 commit e2c36aa
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
125 changes: 125 additions & 0 deletions docs/api/udp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
Use Bun's UDP API to implement services with advanced real-time requirements, such as voice chat.

## Bind a UDP socket (`Bun.udpSocket()`)

To create a new (bound) UDP socket:

```ts
const socket = await Bun.udpSocket({})
console.log(socket.port); // assigned by the operating system
```

Specify a port:
```ts
const socket = await Bun.udpSocket({
port: 41234
})
console.log(socket.port); // 41234
```

### Send a datagram

Specify the data to send, as well as the destination port and address.

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

Note that the address must be a valid IP address - `send` does not perform
DNS resolution, as it is intended for low-latency operations.


### Receive datagrams

When creating your socket, add a callback to specify what should be done when packets are received:

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

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

### Connections

While UDP does not have a concept of a connection, many UDP communications (especially as a client) involve only one peer.
In such cases it can be beneficial to connect the socket to that peer, which specifies to which address all packets are sent
and restricts incoming packets to that peer only.

```ts

const server = await Bun.udpSocket({
socket: {
data(socket, buf, port, addr) {
console.log(`message from ${addr}:${port}:`)
console.log(buf.toString());
}
}
})
const client = await Bun.udpSocket({
connect: {
port: server.port,
hostname: '127.0.0.1',
}
});

client.send("Hello");

```

Because connections are implemented on the operating system level, you can potentially observe performance benefits, too.


### Send many packets at once using `sendMany()`

If you want to send a large volume of packets at once, it can make sense to batch them all together to avoid the overhead
of making a system call for each. This is made possible by the `sendMany()` API:

For an unconnected socket, `sendMany` takes an array as its only argument. Each set of three array elements describes a packet:
The first item is the data to be sent, the second is the target port, and the last is the target address.

```ts
const socket = await Bun.udpSocket({})
// sends 'Hello' to 127.0.0.1:41234, and 'foo' to 1.1.1.1:53 in a single operation
socket.sendMany(['Hello', 41234, '127.0.0.1', 'foo', 53, '1.1.1.1'])
```

With a connected socket, `sendMany` simply takes an array, where each element represents the data to be sent to the peer.

```ts
const socket = await Bun.udpSocket({
connect: {
port: 41234,
hostname: 'localhost',
}
});
socket.sendMany(['foo', 'bar', 'baz']);
```

`sendMany` returns the number of packets that were successfully sent. As with `send`, `sendMany` only takes valid IP addresses
as destinations, as it does not perform DNS resolution.

### Handle backpressure

It may happen that a packet that you're sending does not fit into the operating system's packet buffer. You can detect that this
has happened when:
- `send` returns `false`
- `sendMany` returns a number smaller than the number of packets you specified
In this case, the `drain` socket handler will be called once the socket becomes writable again:

```ts
const socket = await Bun.udpSocket({
socket: {
drain(socket) {
// continue sending data
}
}
});
```
3 changes: 3 additions & 0 deletions docs/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ export default {
page("api/tcp", "TCP sockets", {
description: `Bun's native API implements Web-standard TCP Sockets, plus a Bun-native API for building fast TCP servers.`,
}), // "`Bun.{listen|connect}`")
page("api/tcp", "TCP sockets", {

This comment has been minimized.

Copy link
@yus-ham

yus-ham Apr 27, 2024

Contributor

it should be api/udp

description: `Bun's native API implements fast and flexible UDP sockets.`,
}), // "`Bun.{listen|connect}`")
page("api/globals", "Globals", {
description: `Bun implements a range of Web APIs, Node.js APIs, and Bun-native APIs that are available in the global scope.`,
}), // "`Bun.write`"),
Expand Down
3 changes: 2 additions & 1 deletion docs/runtime/nodejs-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Some methods are not optimized yet.

### [`node:dgram`](https://nodejs.org/api/dgram.html)

🔴 Not implemented.
🟡 Missing `setBroadcast` `setTTL` `setMulticastTTL` `setMulticastLoopback` `setMulticastInterface` `addMembership` `dropMembership`
`addSourceSpecificMembership` `dropSourceSpecificMembership`

### [`node:diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html)

Expand Down

0 comments on commit e2c36aa

Please sign in to comment.