Какие библиотеки использовал для работы с WebSocket?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
WebSocket библиотеки в Node.js: Обзор и сравнение
WebSocket — это протокол для двусторонней коммуникации в реальном времени. Node.js имеет несколько популярных библиотек для работы с WebSocket, каждая со своими особенностями и использованием.
1. Socket.IO
Socket.IO — это самая популярная библиотека для real-time коммуникации. Она обеспечивает WebSocket с fallback на другие транспорты.
Преимущества:
- Автоматический fallback на HTTP long-polling
- Встроенные комнаты (rooms) и пространства имён (namespaces)
- Automatic reconnection с переподключением
- Поддержка acknowledge callbacks
- Простой API для emit/on
Пример:
const express = require("express");
const http = require("http");
const socketIO = require("socket.io");
const app = express();
const server = http.createServer(app);
const io = socketIO(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
}
});
io.on("connection", (socket) => {
console.log("New user connected:", socket.id);
socket.on("message", (data) => {
console.log("Received:", data);
// Отправить сообщение всем клиентам
io.emit("broadcast", { message: data, from: socket.id });
});
// Работа с комнатами
socket.on("join-room", (room) => {
socket.join(room);
io.to(room).emit("user-joined", { userId: socket.id });
});
socket.on("disconnect", () => {
console.log("User disconnected:", socket.id);
});
});
server.listen(3000, () => {
console.log("Server running on port 3000");
});
Фронтенд:
import { io } from "socket.io-client";
const socket = io("http://localhost:3000");
socket.on("connect", () => {
console.log("Connected to server");
socket.emit("message", "Hello from client");
});
socket.on("broadcast", (data) => {
console.log("Received:", data);
});
2. ws
ws — это минималистичная, производительная WebSocket библиотека для Node.js.
Преимущества:
- Быстрая и легкая
- Минимальные зависимости
- Подходит для high-performance приложений
- Полная поддержка WebSocket RFC 6455
Пример:
const WebSocket = require("ws");
const http = require("http");
const server = http.createServer();
const wss = new WebSocket.Server({ server });
wss.on("connection", (ws) => {
console.log("Client connected");
ws.on("message", (message) => {
console.log("Received:", message);
// Отправить ответ клиенту
ws.send(`Server received: ${message}`);
// Broadcast всем подключённым клиентам
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
});
ws.on("close", () => {
console.log("Client disconnected");
});
ws.on("error", (error) => {
console.error("WebSocket error:", error);
});
});
server.listen(3000);
Фронтенд:
const socket = new WebSocket("ws://localhost:3000");
socket.onopen = () => {
console.log("Connected to server");
socket.send("Hello from client");
};
socket.onmessage = (event) => {
console.log("Received:", event.data);
};
socket.onerror = (error) => {
console.error("Error:", error);
};
3. Primus
Primus — это высокоуровневая абстракция для WebSocket с поддержкой разных engines (Socket.IO, ws, Engine.IO и др.).
Преимущества:
- Гибкость в выборе engine
- Unified API для разных WebSocket реализаций
- Plugin система
- Transformer middleware
Пример:
const Primus = require("primus");
const http = require("http");
const server = http.createServer();
const primus = new Primus(server, {
transformer: "websockets",
pathname: "/primus"
});
primus.on("connection", (spark) => {
console.log("New connection:", spark.id);
spark.on("data", (data) => {
console.log("Received:", data);
spark.write(data);
});
spark.on("end", () => {
console.log("Connection closed");
});
});
server.listen(3000);
4. ws + Express Middleware
Комбинация ws и Express для более fine-grained управления.
const express = require("express");
const http = require("http");
const WebSocket = require("ws");
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
// Middleware для аутентификации WebSocket
wss.on("connection", (ws, req) => {
const token = req.url.split("?token=")[1];
if (!validateToken(token)) {
ws.close();
return;
}
ws.on("message", (message) => {
try {
const data = JSON.parse(message);
handleMessage(ws, data);
} catch (error) {
ws.send(JSON.stringify({ error: "Invalid message" }));
}
});
});
function handleMessage(ws, data) {
switch (data.type) {
case "ping":
ws.send(JSON.stringify({ type: "pong" }));
break;
case "echo":
ws.send(JSON.stringify({ echo: data.message }));
break;
default:
ws.send(JSON.stringify({ error: "Unknown message type" }));
}
}
server.listen(3000);
5. GraphQL Subscriptions с WebSocket
Для GraphQL приложений используют apollo-server с WebSocket транспортом.
const { ApolloServer } = require("apollo-server-express");
const { WebSocketServer } = require("ws");
const { useServer } = require("graphql-ws/lib/use/ws");
const express = require("express");
const http = require("http");
const typeDefs = gql`
type Subscription {
messageAdded: String
}
`;
const resolvers = {
Subscription: {
messageAdded: {
subscribe: () => pubsub.asyncIterator(["MESSAGE_ADDED"])
}
}
};
const app = express();
const server = http.createServer(app);
const wsServer = new WebSocketServer({ server, path: "/graphql" });
const apollo = new ApolloServer({
typeDefs,
resolvers
});
await apollo.start();
apollo.applyMiddleware({ app });
useServer({ schema: apollo.schema }, wsServer);
server.listen(4000);
Сравнение библиотек
| Критерий | Socket.IO | ws | Primus | |---|---|---| | Простота | Высокая | Средняя | Средняя | | Производительность | Хорошая | Отличная | Хорошая | | Fallback | Есть | Нет | Опционально | | Комнаты | Встроены | Нет | Нет | | Кривая обучения | Пологая | Крутая | Средняя | | Размер бандла | ~65KB | ~5KB | ~20KB |
Лучшие практики
1. Используй heartbeat для отслеживания соединений
const intervals = new Map();
wss.on("connection", (ws) => {
const interval = setInterval(() => {
if (ws.isAlive === false) return ws.terminate();
ws.isAlive = false;
ws.ping();
}, 30000);
ws.isAlive = true;
ws.on("pong", () => {
ws.isAlive = true;
});
ws.on("close", () => {
clearInterval(interval);
});
});
2. Обрабатывай ошибки и переподключения
socket.on("error", (error) => {
console.error("Connection error:", error);
});
socket.on("disconnect", () => {
console.log("Disconnected from server");
// Может произойти автоматическое переподключение
});
3. Используй JSON для сообщений
const message = {
type: "update",
data: { userId: 123, status: "online" }
};
socket.send(JSON.stringify(message));
Рекомендация
- Socket.IO — для большинства приложений с real-time коммуникацией
- ws — для high-performance систем и микросервисов
- Primus — для гибридных решений с множественными engines