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.