WebSockets
Real-time communication, connection management, reconnection, and state sync.
Overview
WebSockets enable real-time bidirectional communication between client and server.
Key Concepts
- WebSocket API — Browser API for persistent connections
- useWebSocket Hook — Manage connection lifecycle
- Reconnection — Handle disconnections gracefully
- Message Handling — Parse and dispatch incoming messages
- State Synchronization — Keep UI in sync with server state
Code Examples
function useWebSocket(url) {
const [isConnected, setIsConnected] = useState(false);
const [lastMessage, setLastMessage] = useState(null);
const wsRef = useRef(null);
useEffect(() => {
const ws = new WebSocket(url);
wsRef.current = ws;
ws.onopen = () => setIsConnected(true);
ws.onclose = () => {
setIsConnected(false);
setTimeout(() => reconnect(url), 3000);
};
ws.onmessage = (event) => setLastMessage(JSON.parse(event.data));
return () => ws.close();
}, [url]);
const send = useCallback((data) => {
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsRef.current.send(JSON.stringify(data));
}
}, []);
return { isConnected, lastMessage, send };
}
function ChatRoom() {
const { isConnected, lastMessage, send } = useWebSocket('ws://localhost:8080');
const [messages, setMessages] = useState([]);
useEffect(() => {
if (lastMessage) {
setMessages(prev => [...prev, lastMessage]);
}
}, [lastMessage]);
const handleSubmit = (e) => {
e.preventDefault();
send({ type: 'message', text: e.target.message.value });
e.target.reset();
};
return (
<div>
<div className="status">{isConnected ? 'Connected' : 'Disconnected'}</div>
<div className="messages">
{messages.map((msg, i) => <div key={i}>{msg.text}</div>)}
</div>
<form onSubmit={handleSubmit}>
<input name="message" />
<button type="submit">Send</button>
</form>
</div>
);
}
Practice
Build a real-time collaborative editor using WebSockets and operational transformation.