Skip to main content

WebSocket

WebSocket is a global — the standard browser API, for live bidirectional streams (live data feeds, chat, device telemetry).

const ws = new WebSocket('wss://stream.example.com/prices');
ws.onmessage = (e) => console.log(e.data);
ws.onopen = () => ws.send('subscribe:BTC');

A live-value component

A WebSocket pairs naturally with useState: open the socket on mount, push each message into state, and close it on unmount.

import { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from '@kog/ui';

export default function App() {
const [price, setPrice] = useState('-');
const [connected, setConnected] = useState(false);

useEffect(() => {
const ws = new WebSocket('wss://stream.example.com/prices');
ws.onopen = () => {
setConnected(true);
ws.send('subscribe:BTC');
};
ws.onmessage = (e) => {
const msg = JSON.parse(e.data as string);
setPrice(msg.price);
};
ws.onclose = () => setConnected(false);
return () => ws.close();
}, []);

return (
<View style={styles.card}>
<Text style={styles.dot}>{connected ? 'live' : 'offline'}</Text>
<Text style={styles.price}>{price}</Text>
</View>
);
}

const styles = StyleSheet.create({
card: { padding: 20, gap: 8 },
dot: { fontSize: 14, color: '#8a8a9a' },
price: { fontSize: 32, color: '#e8e8f0' },
});

Always close the socket in the effect cleanup (return () => ws.close()), so a hot reload or screen change doesn't leak the connection.

Text and binary frames

onmessage delivers a MessageEvent. For a text frame, e.data is a string; for a binary frame it's an ArrayBuffer (Kog's binaryType defaults to "arraybuffer" — the "blob" mode isn't supported, since there's no Blob).

ws.onmessage = (e) => {
if (typeof e.data === 'string') {
handleText(e.data);
} else {
const bytes = new Uint8Array(e.data);
handleBinary(bytes);
}
};

Send a string, an ArrayBuffer, or a typed array with ws.send(...). Sending before the socket is OPEN throws; guard with ws.readyState === WebSocket.OPEN or send from onopen.

Close and readyState

ws.close(1000, 'done'); // optional code + reason

ws.readyState is one of WebSocket.CONNECTING (0), OPEN (1), CLOSING (2), CLOSED (3). The close event's CloseEvent carries .code, .reason, and .wasClean.

Both handler styles work

You can use the onopen/onmessage/onclose/onerror properties (above) or addEventListener:

ws.addEventListener('message', (e) => console.log(e.data));
ws.addEventListener('close', (e) => console.log(e.code));

In the playground

In the web playground, WebSocket is the browser's own, so it connects to any ws:///wss:// server the browser can reach (subject to the same mixed-content and origin rules as a web page). On a device it's a native WebSocket client with no such constraints.

See the API reference for the complete surface.