UDP
このコンテンツはまだ日本語訳がありません。
UdpSocketActor wraps a UDP socket — connectionless, no
acks, no retries, packet-oriented. Use when best-effort
delivery is fine and latency matters more than reliability.
Inbound datagrams are pushed to a target actor you wire in
through the builder — there is no subscribe command. Sending is a
{ kind: 'send', datagram } message with an explicit destination
(UDP is connectionless, so every packet carries its own address).
import { ActorSystem, UdpSocketActor, UdpSocketOptions } from 'actor-ts';import type { UdpDatagram } from 'actor-ts';
const system = ActorSystem.create('udp-demo');
// Inbound datagrams land here, one message per packet:class PacketHandler extends Actor<UdpDatagram> { override onReceive(d: UdpDatagram): void { // d.payload — Uint8Array // d.remoteHost — sender's address // d.remotePort — sender's port console.log(new TextDecoder().decode(d.payload), 'from', d.remoteHost); }}
const target = system.spawnAnonymous(PacketHandler);
const udpSocketOptions = UdpSocketOptions.create() .withBindPort(41234) // bind for receiving; 0 lets the OS pick .withTarget(target);const udp = system.spawnAnonymous( () => new UdpSocketActor( udpSocketOptions, // required: where inbound packets go ),);
// Send to a remote endpoint:udp.tell({ kind: 'send', datagram: { payload: 'ping', host: '127.0.0.1', port: 41234 },});Settings
Section titled “Settings”UdpSocketOptionsType extends BrokerCommonOptionsType (which
carries the shared reconnect / circuit-breaker / outbound-buffer
fields) and adds:
interface UdpSocketOptionsType extends BrokerCommonOptionsType { bindHost?: string; // default '0.0.0.0' bindPort?: number; // default 0 = OS-assigned type?: 'udp4' | 'udp6'; // default 'udp4' target?: ActorRef<UdpDatagram>; // required: inbound subscriber}target is the only required field — inbound datagrams have
nowhere to go without it. All four are set through the builder:
UdpSocketOptions.create() .withBindHost('0.0.0.0') .withBindPort(41234) .withType('udp4') .withTarget(target);Receiving
Section titled “Receiving”Inbound packets are delivered straight to the target actor — one
UdpDatagram message per packet. There is no subscribe
handshake; wiring the target through .withTarget(..) is the whole
subscription:
class PacketHandler extends Actor<UdpDatagram> { override onReceive(d: UdpDatagram): void { // d.payload — Uint8Array (packet bytes) // d.remoteHost — sender's IP address // d.remotePort — sender's port this.handleDatagram(d.payload, d.remoteHost, d.remotePort); }}
const target = system.spawnAnonymous(PacketHandler);
const udpSocketOptions = UdpSocketOptions.create() .withBindPort(41234) .withTarget(target);const udp = system.spawnAnonymous( () => new UdpSocketActor( udpSocketOptions, ),);Each packet is one logical message — UDP preserves packet
boundaries (unlike TCP’s byte stream), so one datagram in maps to
exactly one UdpDatagram out.
Sending
Section titled “Sending”Send with a { kind: 'send', datagram } message. The datagram
carries its own destination — host and port — plus the
payload, which may be a string (UTF-8 encoded for you) or a raw
Uint8Array (sent verbatim):
udp.tell({ kind: 'send', datagram: { payload: 'ping', host: '127.0.0.1', port: 41234 },});
udp.tell({ kind: 'send', datagram: { payload: new Uint8Array([0xde, 0xad]), host: '10.0.0.5', port: 8125 },});Send-only
Section titled “Send-only”A target is required, but if the actor only ever sends you can
still leave binding to the OS. Omit withBindPort (or pass 0)
and the socket binds to an ephemeral port — a pure sender for
one-way telemetry (statsd, syslog):
const udpSocketOptions = UdpSocketOptions.create().withTarget(target);new UdpSocketActor( udpSocketOptions, // OS-assigned port, send-only in practice);When to use UDP
Section titled “When to use UDP”Three good fits:
- Telemetry — sending metrics to a collector (statsd, DogStatsD). Loss of one packet is acceptable; latency matters.
- Service discovery on a LAN — mDNS / SSDP / proprietary broadcast schemes.
- High-frequency low-stakes data — game positions, sensor streams where the next packet supersedes the previous.
Not the right shape for:
- Anything that needs delivery guarantee — use TCP, or a higher-level reliable protocol.
- Anything requiring ordering — UDP packets arrive in any order.
- Anything larger than MTU — packets >1500 bytes fragment + can drop more easily.
Settings resolve with the usual precedence — explicit builder
options override HOCON, which overrides the built-in defaults. The
config namespace is actor-ts.io.broker.udp:
actor-ts.io.broker.udp { bindHost = "0.0.0.0" bindPort = 41234 type = "udp4"}Where to next
Section titled “Where to next”- I/O overview — the bigger picture.
- TCP — for reliable byte streams.
- BrokerActor base — the shared lifecycle.
