Skip to main content

Sockets

For protocols below HTTP, such as a raw TCP service, a UDP sensor feed, or a small on-device server, Kog gives you TCPSocket, UDPSocket, and TCPServer as globals. The API is Kog-native: promises for connect/bind/listen, and onX(cb) callbacks that return an unsubscribe function. It is intentionally neither node's net/dgram nor a browser API.

Not in the web playground

A browser has no raw sockets, so new TCPSocket() / UDPSocket() / TCPServer() throw KogNetUnavailableError in the playground. Run these on a device (kog flash) or the desktop simulator (kog dev). fetch and WebSocket cover most needs and work everywhere.

See it for yourself. This runs in the playground, so new TCPSocket() throws the helpful error. On a device or kog dev, it would construct fine:

Binary in, string or binary out​

Inbound data is always an ArrayBuffer, never a string or a node Buffer. When you want text, decode it with TextDecoder. When you send, you may pass a string (UTF-8 encoded for you), an ArrayBuffer, or a typed array.

TCP client​

const socket = new TCPSocket();
await socket.connect('192.168.1.50', 8080);

const off = socket.onData((chunk) => {
const text = new TextDecoder().decode(chunk);
console.log('got', text);
});

socket.onError((err) => console.error(err.code));
socket.onClose(() => console.log('closed'));

socket.send('GET /status\n');
// ...later
off(); // unsubscribe this listener
await socket.close(); // graceful close

connect resolves once the connection is established (after the TLS handshake if you pass { tls: true }), and rejects with a KogNetError on refusal or timeout. Pace large sends with socket.bufferedAmount and socket.onDrain(...).

Device limitations today

The desktop simulator implements all of the above. On the device:

  • { tls: true } is ignored, so the connection is plaintext.
  • onDrain doesn't fire, and bufferedAmount keeps the value from the last send.
  • close() can drop bytes still queued in Kog's send buffer, so let sends drain before closing.

UDP​

const udp = new UDPSocket();
await udp.bind(41234);

udp.onMessage((msg, rinfo) => {
console.log(`${rinfo.address}:${rinfo.port} sent ${msg.byteLength} bytes`);
});

udp.send('ping', 41234, '192.168.1.50');

onMessage delivers the datagram as an ArrayBuffer plus an rinfo with the sender's address, port, family, and size. The host you send to must be an IPv4 address or 'localhost' (a hostname fails with NET_DNS), and broadcast and multicast aren't supported yet.

A tiny TCP server (on-device)​

Because a Kog device is a real network host, it can listen:

const server = new TCPServer();
await server.listen(8080);

server.onConnection((conn) => {
conn.onData((chunk) => {
// echo it back
conn.send(chunk);
});
});

Each onConnection callback receives an already-open TCPSocket. await server.close() stops accepting new connections; existing ones keep running.

Errors​

Socket failures reject or emit a KogNetError with a stable .code string. Branch on the string, never a raw number:

try {
await socket.connect(host, port);
} catch (err) {
if (err instanceof KogNetError && err.code === 'NET_CONNREFUSED') {
// nothing listening there
}
}

The code list (NET_TIMEOUT, NET_RESET, NET_TLS, OOM, …) is in the API reference.