TL;DR
WebSockets zapewniają dwukierunkową komunikację w czasie rzeczywistym między klientem a serwerem. Idealne dla chatów, notyfikacji, live updates i gier. Oto kiedy używać WebSockets i jak je implementować w 2026.
Dla kogo to jest
- Deweloperów budujących real-time features
- Firm potrzebujących live updates
- Zespołów pracujących nad aplikacjami interaktywnymi
Fraza (SEO)
websockets, real-time communication, socket.io, live updates, bidirectional communication
Czym są WebSockets?
WebSocket to protokół komunikacji:
- Dwukierunkowa komunikacja (client ↔ server)
- Persistent connection (nie zamyka się)
- Niski overhead (vs HTTP polling)
- Real-time updates
Porównanie z HTTP:
- HTTP: request → response, connection zamyka się
- WebSocket: persistent connection, obie strony mogą wysyłać dane
Kiedy używać:
- ✅ Chat, messaging
- ✅ Live notifications
- ✅ Real-time dashboards
- ✅ Collaborative editing
- ✅ Gaming
- ❌ Proste CRUD operations (HTTP wystarczy)
Podstawowa implementacja
Node.js z ws
Server:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
console.log('Client connected');
// Wysyłanie wiadomości do klienta
ws.send('Welcome to WebSocket server!');
// Odbieranie wiadomości od klienta
ws.on('message', (message) => {
console.log('Received:', message.toString());
// Broadcast do wszystkich klientów
wss.clients.forEach((client) => {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(`Broadcast: ${message}`);
}
});
});
ws.on('close', () => {
console.log('Client disconnected');
});
});
Client (Browser):
const ws = new WebSocket('ws://localhost:8080');
ws.onopen = () => {
console.log('Connected');
ws.send('Hello Server!');
};
ws.onmessage = (event) => {
console.log('Received:', event.data);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Disconnected');
};
Socket.io
Podstawowa konfiguracja
Server:
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
}
});
io.on('connection', (socket) => {
console.log('User connected:', socket.id);
// Odbieranie wiadomości
socket.on('message', (data) => {
console.log('Message:', data);
// Broadcast do wszystkich
io.emit('message', {
id: socket.id,
text: data.text,
timestamp: new Date()
});
});
// Room-based messaging
socket.on('join-room', (roomId) => {
socket.join(roomId);
io.to(roomId).emit('user-joined', socket.id);
});
socket.on('room-message', ({ roomId, message }) => {
io.to(roomId).emit('message', message);
});
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
});
server.listen(3001, () => {
console.log('Server running on port 3001');
});
Client:
import { io } from 'socket.io-client';
const socket = io('http://localhost:3001');
socket.on('connect', () => {
console.log('Connected:', socket.id);
// Dołącz do pokoju
socket.emit('join-room', 'room-123');
// Wyślij wiadomość
socket.emit('message', { text: 'Hello!' });
});
socket.on('message', (data) => {
console.log('Received:', data);
});
socket.on('disconnect', () => {
console.log('Disconnected');
});
Use Cases
1. Chat Application
Features:
- Real-time messaging
- Typing indicators
- Online/offline status
- Message delivery status
Implementacja:
// Server
io.on('connection', (socket) => {
socket.on('send-message', (data) => {
// Zapisz do bazy danych
saveMessage(data);
// Wyślij do odbiorcy
io.to(data.recipientId).emit('new-message', data);
// Potwierdzenie nadawcy
socket.emit('message-sent', { id: data.id });
});
socket.on('typing', ({ recipientId, isTyping }) => {
socket.to(recipientId).emit('user-typing', {
userId: socket.id,
isTyping
});
});
});
2. Live Notifications
Real-time powiadomienia:
// Server
io.on('connection', (socket) => {
// Autoryzacja
const userId = authenticate(socket);
socket.join(`user-${userId}`);
// Wysyłanie notyfikacji
function sendNotification(userId, notification) {
io.to(`user-${userId}`).emit('notification', notification);
}
});
// Trigger z innej części aplikacji
sendNotification(userId, {
type: 'new-comment',
message: 'Someone commented on your post',
link: '/post/123'
});
3. Real-time Dashboard
Live metrics:
// Server - wysyłanie danych co sekundę
setInterval(() => {
const metrics = {
users: getActiveUsers(),
revenue: getRevenue(),
orders: getOrders()
};
io.emit('metrics-update', metrics);
}, 1000);
4. Collaborative Editing
Wspólna edycja dokumentów:
// Server
io.on('connection', (socket) => {
socket.on('join-document', (docId) => {
socket.join(`doc-${docId}`);
});
socket.on('document-change', ({ docId, changes }) => {
// Zastosuj zmiany
applyChanges(docId, changes);
// Broadcast do innych użytkowników
socket.to(`doc-${docId}`).emit('document-updated', changes);
});
});
Best Practices
1. Authentication
Autoryzacja połączenia:
io.use((socket, next) => {
const token = socket.handshake.auth.token;
if (verifyToken(token)) {
socket.userId = getUserIdFromToken(token);
next();
} else {
next(new Error('Authentication failed'));
}
});
2. Error Handling
Obsługa błędów:
socket.on('error', (error) => {
console.error('Socket error:', error);
socket.emit('error', { message: 'Something went wrong' });
});
// Reconnection
socket.on('disconnect', (reason) => {
if (reason === 'io server disconnect') {
// Server disconnect, reconnect manually
socket.connect();
}
});
3. Rate Limiting
Ograniczenie liczby wiadomości:
const rateLimit = new Map();
io.on('connection', (socket) => {
rateLimit.set(socket.id, { count: 0, resetTime: Date.now() + 60000 });
socket.on('message', (data) => {
const limit = rateLimit.get(socket.id);
if (Date.now() > limit.resetTime) {
limit.count = 0;
limit.resetTime = Date.now() + 60000;
}
if (limit.count >= 10) {
socket.emit('error', { message: 'Rate limit exceeded' });
return;
}
limit.count++;
// Process message
});
});
4. Room Management
Efektywne zarządzanie pokojami:
// Dołącz do pokoju
socket.on('join-room', (roomId) => {
socket.leaveAll(); // Opuść poprzednie pokoje
socket.join(roomId);
});
// Broadcast tylko do pokoju
io.to(roomId).emit('message', data);
5. Heartbeat/Ping
Utrzymanie połączenia:
// Server
setInterval(() => {
io.emit('ping');
}, 30000);
// Client
socket.on('ping', () => {
socket.emit('pong');
});
WebSockets vs Alternatives
WebSockets vs HTTP Polling
HTTP Polling:
// Client pyta co sekundę
setInterval(() => {
fetch('/api/updates')
.then(res => res.json())
.then(data => updateUI(data));
}, 1000);
WebSockets:
- ✅ Mniej overhead
- ✅ Real-time (bez opóźnienia)
- ✅ Server może wysyłać kiedy chce
- ❌ Większa złożoność
WebSockets vs Server-Sent Events (SSE)
SSE:
- ✅ Prostsze (tylko server → client)
- ✅ Automatyczne reconnection
- ❌ Tylko jednokierunkowe
- ❌ Brak wsparcia w IE
WebSockets:
- ✅ Dwukierunkowe
- ✅ Lepsze dla interaktywnych aplikacji
Scaling WebSockets
Redis Adapter (Socket.io)
Dla wielu serwerów:
const { createAdapter } = require('@socket.io/redis-adapter');
const { createClient } = require('redis');
const pubClient = createClient({ host: 'localhost', port: 6379 });
const subClient = pubClient.duplicate();
io.adapter(createAdapter(pubClient, subClient));
Load Balancing
Sticky sessions:
- WebSockets wymagają persistent connection
- Używaj sticky sessions w load balancerze
- Lub Redis adapter dla multi-server
FAQ
Kiedy używać WebSockets zamiast HTTP?
Gdy potrzebujesz real-time, dwukierunkowej komunikacji. Dla prostych CRUD operacji HTTP wystarczy.
Czy WebSockets działają przez proxy?
Tak, ale wymagają odpowiedniej konfiguracji (upgrade headers). Większość nowoczesnych proxy wspiera WebSockets.
Jak testować WebSockets?
Używaj narzędzi jak Postman (WebSocket support) lub napisz testy z ws library.