Что такое WebSocket
▸Определение
WebSocket — протокол для постоянного соединения между клиентом и сервером. Позволяет обмениваться данными в реальном времени.
▸HTTP vs WebSocket
Socket.io
▸Установка
1npm install socket.io
▸Сервер
1import { Server } from 'socket.io';23const io = new Server(3000, {4 cors: {5 origin: 'http://localhost:5173',6 },7});89io.on('connection', (socket) => {10 console.log('Клиент подключился:', socket.id);1112 socket.on('message', (data) => {13 io.emit('message', data);14 });1516 socket.on('disconnect', () => {17 console.log('Клиент отключился:', socket.id);18 });19});
▸Клиент
1<script src="/socket.io/socket.io.js"></script>2<script>3 const socket = io('http://localhost:3000');45 socket.emit('message', 'Привет сервер!');6 socket.on('message', (data) => {7 console.log('Сообщение:', data);8 });9</script>
Комнаты в Socket.io
1io.on('connection', (socket) => {2 socket.on('join-room', (roomId) => {3 socket.join(roomId);4 });56 socket.on('send-message', ({ roomId, message }) => {7 io.to(roomId).emit('message', message);8 });9});
Middleware в Socket.io
1io.use((socket, next) => {2 const token = socket.handshake.auth.token;3 const user = verifyToken(token);4 if (!user) {5 return next(new Error('Не авторизован'));6 }7 socket.user = user;8 next();9});
Server-Sent Events (SSE)
▸Сервер
1import express from 'express';23const app = express();45app.get('/events', (req, res) => {6 res.setHeader('Content-Type', 'text/event-stream');7 res.setHeader('Cache-Control', 'no-cache');8 res.setHeader('Connection', 'keep-alive');910 const sendEvent = (data) => {11 res.write(`data: ${JSON.stringify(data)}\n\n`);12 };1314 // Отправка событий15 setInterval(() => {16 sendEvent({ time: new Date().toISOString() });17 }, 1000);1819 req.on('close', () => {20 // Очистка при отключении21 });22});
▸Клиент
1const eventSource = new EventSource('/events');23eventSource.onmessage = (event) => {4 const data = JSON.parse(event.data);5 console.log('Получено:', data);6};78eventSource.onerror = (error) => {9 console.error('Ошибка:', error);10};
WebSocket vs SSE
▸Когда использовать WebSocket
▸Когда использовать SSE
Пример: чат на Socket.io
1// Сервер2io.on('connection', (socket) => {3 socket.on('join', (username) => {4 socket.username = username;5 io.emit('user-connected', username);6 });78 socket.on('chat-message', (message) => {9 io.emit('chat-message', {10 message,11 username: socket.username,12 time: new Date().toISOString(),13 });14 });1516 socket.on('disconnect', () => {17 io.emit('user-disconnected', socket.username);18 });19});
Пример: уведомления на SSE
1// Сервер2app.get('/notifications', (req, res) => {3 res.setHeader('Content-Type', 'text/event-stream');4 res.setHeader('Cache-Control', 'no-cache');5 res.setHeader('Connection', 'keep-alive');67 const sendNotification = (notification) => {8 res.write(`event: notification\n`);9 res.write(`data: ${JSON.stringify(notification)}\n\n`);10 };1112 // Подписка на Redis pub/sub для уведомлений13 redis.subscribe('notifications', (message) => {14 sendNotification(JSON.parse(message));15 });16});
Масштабирование
▸Redis adapter для Socket.io
1import { createAdapter } from '@socket.io/redis-adapter';2import { createClient } from 'redis';34const pubClient = createClient();5const subClient = pubClient.duplicate();67io.adapter(createAdapter(pubClient, subClient));
Безопасность
1const io = new Server(3000, {2 cors: {3 origin: 'https://example.com',4 credentials: true,5 },6});78// Аутентификация9io.use((socket, next) => {10 const token = socket.handshake.auth.token;11 if (!verifyToken(token)) {12 return next(new Error('Не авторизован'));13 }14 next();15});
Заключение
WebSocket и SSE — две технологии для real-time. Socket.io предоставляет WebSocket с fallback и дополнительными возможностями. SSE проще для однонаправленных обновлений. Выбирайте исходя из требований приложения.