DevToolBoxKOSTENLOS
Blog

Socket.IO: Der Komplette Leitfaden für Echtzeit-Kommunikation

20 min readvon DevToolBox Team

TL;DR

Socket.IO is a battle-tested library for real-time bidirectional communication. It wraps WebSocket with automatic reconnection, rooms, namespaces, and HTTP fallback. Install the server with npm install socket.io and the client with npm install socket.io-client. Use emit/on for events, join/to for rooms, JWT middleware for auth, and the Redis adapter for horizontal scaling.

Key Takeaways

  • Socket.IO provides WebSocket with automatic fallback, reconnection, and multiplexing
  • Use emit/on for sending and receiving events between client and server
  • Rooms group sockets for targeted broadcasting; namespaces separate concerns
  • Authenticate connections using JWT middleware in the handshake phase
  • Scale horizontally with the Redis adapter for multi-server deployments
  • Use acknowledgements for request-response patterns over sockets
  • Socket.IO works with Express, Next.js, and integrates cleanly with React hooks
  • Enable binary parser and compression for high-throughput production scenarios

What is Socket.IO?

Socket.IO is a JavaScript library that enables real-time, bidirectional, event-based communication between web clients and servers. Originally created in 2010, it has become the most widely adopted solution for adding real-time features to Node.js applications, powering chat apps, live dashboards, collaborative editors, multiplayer games, and IoT systems.

Unlike raw WebSocket, Socket.IO is a higher-level abstraction that adds critical production features: automatic reconnection with exponential backoff, packet buffering during disconnections, broadcasting to rooms of clients, multiplexing via namespaces, and transparent fallback to HTTP long-polling when WebSocket is blocked by proxies or firewalls.

Socket.IO vs WebSocket Comparison

FeatureRaw WebSocketSocket.IO
Auto-reconnectionManual implementationBuilt-in with backoff
Fallback transportNoneHTTP long-polling
Rooms / GroupsManual implementationBuilt-in
NamespacesNot availableBuilt-in multiplexing
Binary supportManual parsingAutomatic detection
AcknowledgementsManual implementationBuilt-in callbacks
BroadcastingIterate connectionsOne-liner API
Protocol overheadMinimalSlightly higher

Installation

Server Installation

# Install the Socket.IO server
npm install socket.io

# Or with yarn
yarn add socket.io

# Or with pnpm
pnpm add socket.io

Client Installation

# Install the Socket.IO client
npm install socket.io-client

# Or load from CDN
# <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>

Minimal Server Setup

// server.js
const { createServer } = require("http");
const { Server } = require("socket.io");

const httpServer = createServer();
const io = new Server(httpServer, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST"]
  }
});

io.on("connection", (socket) => {
  console.log("Client connected:", socket.id);

  socket.on("disconnect", (reason) => {
    console.log("Client disconnected:", reason);
  });
});

httpServer.listen(3001, () => {
  console.log("Socket.IO server running on port 3001");
});

Minimal Client Setup

// client.js
import { io } from "socket.io-client";

const socket = io("http://localhost:3001");

socket.on("connect", () => {
  console.log("Connected with ID:", socket.id);
});

socket.on("disconnect", (reason) => {
  console.log("Disconnected:", reason);
});

Basic Events: emit and on

Socket.IO uses an event-driven architecture. The server and client communicate by emitting and listening for named events. You can send any serializable data — objects, arrays, strings, buffers — as the event payload.

// Server: listen for events and emit responses
io.on("connection", (socket) => {
  // Listen for a custom event
  socket.on("chat:message", (data) => {
    console.log("Message from", socket.id, ":", data);
    // Broadcast to all OTHER clients
    socket.broadcast.emit("chat:message", {
      userId: socket.id,
      text: data.text,
      timestamp: Date.now()
    });
  });

  // Emit to THIS client only
  socket.emit("welcome", { message: "Hello from server!" });
});

// Client: emit events and listen for responses
socket.emit("chat:message", { text: "Hello everyone!" });

socket.on("chat:message", (data) => {
  console.log("New message:", data.text);
});

socket.on("welcome", (data) => {
  console.log(data.message);
});

Rooms and Namespaces

Rooms

Rooms are server-side groupings of sockets. They let you broadcast messages to a subset of connected clients. Common use cases include chat rooms, game lobbies, and per-user notification channels.

io.on("connection", (socket) => {
  // Join a room
  socket.on("room:join", (roomName) => {
    socket.join(roomName);
    console.log(socket.id, "joined room:", roomName);

    // Notify others in the room
    socket.to(roomName).emit("room:user-joined", {
      userId: socket.id
    });
  });

  // Leave a room
  socket.on("room:leave", (roomName) => {
    socket.leave(roomName);
    socket.to(roomName).emit("room:user-left", {
      userId: socket.id
    });
  });

  // Send message to a specific room
  socket.on("room:message", ({ roomName, text }) => {
    io.to(roomName).emit("room:message", {
      userId: socket.id,
      text,
      timestamp: Date.now()
    });
  });
});

Namespaces

Namespaces allow you to split the logic of your application over a single shared connection (multiplexing). Each namespace has its own event handlers, rooms, and middleware.

// Server: define namespaces
const chatNsp = io.of("/chat");
const adminNsp = io.of("/admin");

chatNsp.on("connection", (socket) => {
  console.log("User connected to /chat");
  socket.on("message", (data) => {
    chatNsp.emit("message", data);
  });
});

adminNsp.use((socket, next) => {
  // Admin-only middleware
  if (socket.handshake.auth.role === "admin") {
    next();
  } else {
    next(new Error("Unauthorized"));
  }
});

adminNsp.on("connection", (socket) => {
  console.log("Admin connected to /admin");
});

// Client: connect to a namespace
const chatSocket = io("http://localhost:3001/chat");
const adminSocket = io("http://localhost:3001/admin", {
  auth: { role: "admin", token: "jwt_token_here" }
});

Broadcasting Patterns

Socket.IO provides several broadcasting patterns to target different sets of clients:

io.on("connection", (socket) => {
  // 1. Emit to the sender only
  socket.emit("private", { msg: "only you" });

  // 2. Broadcast to everyone EXCEPT the sender
  socket.broadcast.emit("announcement", { msg: "new user" });

  // 3. Emit to ALL connected clients (including sender)
  io.emit("global", { msg: "hello world" });

  // 4. Emit to all clients in a room (including sender)
  io.to("room1").emit("room-msg", { msg: "hi room" });

  // 5. Emit to all clients in a room EXCEPT sender
  socket.to("room1").emit("room-msg", { msg: "hi room" });

  // 6. Emit to multiple rooms
  io.to("room1").to("room2").emit("multi", { msg: "hi" });

  // 7. Emit to all clients EXCEPT those in a room
  io.except("room1").emit("others", { msg: "not room1" });
});

Acknowledgements (Request-Response)

Acknowledgements let you implement a request-response pattern over Socket.IO. The emitter passes a callback, and the receiver invokes it to send a response back.

// Server: respond with acknowledgement
io.on("connection", (socket) => {
  socket.on("order:create", (orderData, callback) => {
    try {
      const order = createOrder(orderData);
      callback({ status: "ok", order });
    } catch (err) {
      callback({ status: "error", message: err.message });
    }
  });
});

// Client: emit with callback
socket.emit("order:create", { item: "laptop", qty: 1 }, (response) => {
  if (response.status === "ok") {
    console.log("Order created:", response.order.id);
  } else {
    console.error("Failed:", response.message);
  }
});

// With timeout (Socket.IO v4.4+)
socket.timeout(5000).emit("order:create", data, (err, response) => {
  if (err) {
    console.error("Server did not respond in time");
  } else {
    console.log("Response:", response);
  }
});

Middleware

Middleware functions execute during the handshake phase, before the connection event fires. They are ideal for authentication, rate limiting, and logging.

// Middleware runs once per connection attempt
io.use((socket, next) => {
  const startTime = Date.now();
  console.log("Connection attempt from:", socket.handshake.address);

  // Attach metadata
  socket.data.connectedAt = startTime;

  next(); // Call next() to allow connection
});

// Chain multiple middleware
io.use(rateLimitMiddleware);
io.use(authMiddleware);
io.use(loggingMiddleware);

// Reject a connection
io.use((socket, next) => {
  const ip = socket.handshake.address;
  if (isBlacklisted(ip)) {
    next(new Error("Forbidden"));
  } else {
    next();
  }
});

Authentication with JWT

The most common pattern is to validate a JWT token during the handshake. The client sends the token via the auth option, and the server verifies it in middleware.

// Server: JWT authentication middleware
const jwt = require("jsonwebtoken");

io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  if (!token) {
    return next(new Error("Authentication required"));
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    socket.data.user = decoded;
    next();
  } catch (err) {
    next(new Error("Invalid or expired token"));
  }
});

io.on("connection", (socket) => {
  console.log("Authenticated user:", socket.data.user.email);
  // Join a user-specific room for targeted notifications
  socket.join("user:" + socket.data.user.id);
});

// Client: send JWT token
const socket = io("http://localhost:3001", {
  auth: {
    token: localStorage.getItem("accessToken")
  }
});

// Handle auth errors
socket.on("connect_error", (err) => {
  if (err.message === "Invalid or expired token") {
    // Refresh token and retry
    refreshToken().then((newToken) => {
      socket.auth.token = newToken;
      socket.connect();
    });
  }
});

Error Handling

Proper error handling is critical for production Socket.IO applications. Handle errors at both the connection and event levels.

// Server: comprehensive error handling
io.on("connection", (socket) => {
  // Catch-all listener for debugging
  socket.onAny((eventName, ...args) => {
    console.log("Event:", eventName, args);
  });

  // Handle errors on individual events
  socket.on("data:save", async (data, callback) => {
    try {
      const result = await saveToDatabase(data);
      callback({ success: true, result });
    } catch (error) {
      console.error("Save failed:", error);
      callback({ success: false, error: error.message });
    }
  });

  // Handle socket errors
  socket.on("error", (err) => {
    console.error("Socket error:", err);
  });
});

// Server-level engine errors
io.engine.on("connection_error", (err) => {
  console.error("Connection error:", err.code, err.message);
});

// Client: error handling
socket.on("connect_error", (err) => {
  console.error("Connection failed:", err.message);
});

socket.on("disconnect", (reason) => {
  if (reason === "io server disconnect") {
    // Server forcefully disconnected; manual reconnect needed
    socket.connect();
  }
  // Otherwise, auto-reconnect kicks in
});

Binary Data Transfer

Socket.IO automatically detects and handles binary data. You can send ArrayBuffers, Blobs, and Buffers without any special configuration.

// Client: send a file as binary
const fileInput = document.getElementById("file");
fileInput.addEventListener("change", (e) => {
  const file = e.target.files[0];
  const reader = new FileReader();
  reader.onload = () => {
    socket.emit("file:upload", {
      name: file.name,
      type: file.type,
      data: reader.result // ArrayBuffer
    });
  };
  reader.readAsArrayBuffer(file);
});

// Server: receive binary data
socket.on("file:upload", ({ name, type, data }) => {
  const buffer = Buffer.from(data);
  fs.writeFileSync("uploads/" + name, buffer);
  socket.emit("file:uploaded", { name, size: buffer.length });
});

Scaling with Redis Adapter

When running multiple Socket.IO server instances behind a load balancer, events emitted on one server must reach clients connected to other servers. The Redis adapter solves this using Redis Pub/Sub.

# Install the Redis adapter
npm install @socket.io/redis-adapter redis
// server.js with Redis adapter
const { Server } = require("socket.io");
const { createAdapter } = require("@socket.io/redis-adapter");
const { createClient } = require("redis");

const io = new Server(httpServer);

const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
  io.adapter(createAdapter(pubClient, subClient));
  httpServer.listen(3001);
  console.log("Server with Redis adapter ready");
});

// Now io.emit() reaches ALL clients across ALL servers
// io.to("room1").emit() also works cross-server

For sticky sessions (required for HTTP long-polling transport), configure your load balancer to route requests from the same client to the same server based on the sid query parameter or a cookie.

Socket.IO with Express

const express = require("express");
const { createServer } = require("http");
const { Server } = require("socket.io");

const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
  cors: { origin: "*" }
});

// Express routes
app.get("/api/health", (req, res) => {
  res.json({ status: "ok", connections: io.engine.clientsCount });
});

// REST endpoint that triggers Socket.IO event
app.post("/api/notifications", express.json(), (req, res) => {
  const { userId, message } = req.body;
  io.to("user:" + userId).emit("notification", { message });
  res.json({ sent: true });
});

// Socket.IO handlers
io.on("connection", (socket) => {
  console.log("Connected:", socket.id);
});

httpServer.listen(3001);

Socket.IO with Next.js

Since Next.js API routes are serverless by default, you need a custom server to run Socket.IO. Create a server.js at the project root.

// server.js (Next.js custom server)
const { createServer } = require("http");
const next = require("next");
const { Server } = require("socket.io");

const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const httpServer = createServer((req, res) => {
    handle(req, res);
  });

  const io = new Server(httpServer, {
    cors: { origin: "*" }
  });

  // Make io accessible globally (for API routes)
  global.io = io;

  io.on("connection", (socket) => {
    console.log("Client connected:", socket.id);
  });

  httpServer.listen(3000, () => {
    console.log("Next.js + Socket.IO on port 3000");
  });
});

React Hooks Integration

Create a reusable custom hook that manages the Socket.IO connection lifecycle, event subscriptions, and cleanup automatically.

// hooks/useSocket.ts
import { useEffect, useRef, useState, useCallback } from "react";
import { io, Socket } from "socket.io-client";

export function useSocket(url: string, options?: object) {
  const socketRef = useRef<Socket | null>(null);
  const [isConnected, setIsConnected] = useState(false);

  useEffect(() => {
    const socket = io(url, options);
    socketRef.current = socket;

    socket.on("connect", () => setIsConnected(true));
    socket.on("disconnect", () => setIsConnected(false));

    return () => {
      socket.disconnect();
    };
  }, [url]);

  const emit = useCallback(
    (event: string, data?: any) => {
      socketRef.current?.emit(event, data);
    },
    []
  );

  return { socket: socketRef.current, isConnected, emit };
}

useSocketEvent Hook

// hooks/useSocketEvent.ts
import { useEffect } from "react";
import type { Socket } from "socket.io-client";

export function useSocketEvent<T = any>(
  socket: Socket | null,
  event: string,
  handler: (data: T) => void
) {
  useEffect(() => {
    if (!socket) return;
    socket.on(event, handler);
    return () => {
      socket.off(event, handler);
    };
  }, [socket, event, handler]);
}

Using the Hooks in a Chat Component

// components/Chat.tsx
import { useState, useCallback } from "react";
import { useSocket } from "../hooks/useSocket";
import { useSocketEvent } from "../hooks/useSocketEvent";

interface Message {
  userId: string;
  text: string;
  timestamp: number;
}

export function Chat({ room }: { room: string }) {
  const { socket, isConnected, emit } = useSocket(
    "http://localhost:3001"
  );
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState("");

  useSocketEvent<Message>(socket, "chat:message", 
    useCallback((msg) => {
      setMessages((prev) => [...prev, msg]);
    }, [])
  );

  const sendMessage = () => {
    if (!input.trim()) return;
    emit("chat:message", { room, text: input });
    setInput("");
  };

  return (
    <div>
      <p>Status: {isConnected ? "Connected" : "Disconnected"}</p>
      <div>
        {messages.map((m, i) => (
          <div key={i}>{m.text}</div>
        ))}
      </div>
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        onKeyDown={(e) => e.key === "Enter" && sendMessage()}
      />
      <button onClick={sendMessage}>Send</button>
    </div>
  );
}

Testing Socket.IO

Test your Socket.IO server by creating real client connections in your test suite. Use the socket.io-client package and a testing framework like Jest or Vitest.

// __tests__/socket.test.ts
import { createServer } from "http";
import { Server } from "socket.io";
import { io as Client } from "socket.io-client";
import type { Socket as ClientSocket } from "socket.io-client";

describe("Socket.IO Server", () => {
  let ioServer: Server;
  let clientSocket: ClientSocket;
  let httpServer: ReturnType<typeof createServer>;

  beforeAll((done) => {
    httpServer = createServer();
    ioServer = new Server(httpServer);
    httpServer.listen(() => {
      const addr = httpServer.address();
      const port = typeof addr === "object" ? addr?.port : 0;
      clientSocket = Client(
        "http://localhost:" + port
      );
      clientSocket.on("connect", done);
    });
  });

  afterAll(() => {
    ioServer.close();
    clientSocket.disconnect();
  });

  test("should echo messages", (done) => {
    ioServer.on("connection", (socket) => {
      socket.on("ping", (data) => {
        socket.emit("pong", data);
      });
    });

    clientSocket.emit("ping", { value: 42 });
    clientSocket.on("pong", (data) => {
      expect(data.value).toBe(42);
      done();
    });
  });

  test("should join rooms", (done) => {
    ioServer.on("connection", (socket) => {
      socket.join("test-room");
      ioServer.to("test-room").emit("room-msg", "hello");
    });

    clientSocket.on("room-msg", (data) => {
      expect(data).toBe("hello");
      done();
    });
  });
});

Debugging Socket.IO

Socket.IO uses the debug module internally. Enable verbose logging by setting the DEBUG environment variable.

# Server-side: enable all Socket.IO debug logs
DEBUG=socket.io* node server.js

# Server-side: only engine-level logs
DEBUG=engine* node server.js

# Client-side: enable in browser console
# localStorage.debug = "socket.io-client:socket";

# Client-side: enable all client debug logs
# localStorage.debug = "*";

You can also use the Socket.IO Admin UI, a visual dashboard that lets you inspect connected sockets, rooms, and events in real time.

# Install admin UI
npm install @socket.io/admin-ui
// Enable admin UI on the server
const { instrument } = require("@socket.io/admin-ui");

instrument(io, {
  auth: false, // Set to true in production
  mode: "development"
});
// Open https://admin.socket.io to view the dashboard

Performance Optimization

Follow these best practices to maximize Socket.IO throughput and minimize latency in production:

Skip HTTP polling upgrade

If your infrastructure supports WebSocket, connect directly to avoid the polling-to-WebSocket upgrade overhead.

Use binary parser

For binary-heavy workloads, use @socket.io/msgpack-parser for smaller payloads and faster serialization.

Enable per-message compression

Compress large messages with the perMessageDeflate option to reduce bandwidth.

Batch events

Instead of emitting many small events, batch them into a single event with an array payload.

Use volatile events

For non-critical data like cursor positions, use socket.volatile.emit() to allow dropped messages.

Limit payload size

Set maxHttpBufferSize to prevent clients from sending oversized payloads that consume server memory.

Connection state recovery

Enable connectionStateRecovery in Socket.IO v4.6+ to resume sessions without re-syncing state.

// Performance-optimized server configuration
const io = new Server(httpServer, {
  // Skip HTTP long-polling, start with WebSocket
  transports: ["websocket"],

  // Limit max payload to 1MB
  maxHttpBufferSize: 1e6,

  // Enable per-message compression
  perMessageDeflate: {
    threshold: 1024 // Only compress payloads > 1KB
  },

  // Ping interval and timeout
  pingInterval: 25000,
  pingTimeout: 20000,

  // Connection state recovery (v4.6+)
  connectionStateRecovery: {
    maxDisconnectionDuration: 2 * 60 * 1000,
    skipMiddlewares: true
  }
});

// Client: connect with WebSocket only
const socket = io("http://localhost:3001", {
  transports: ["websocket"]
});
// Volatile events for non-critical data
socket.volatile.emit("cursor:move", { x: 150, y: 300 });

// Batching: send multiple items in one event
const batch = [];
function queueEvent(data) {
  batch.push(data);
  if (batch.length >= 50) {
    socket.emit("events:batch", batch);
    batch.length = 0;
  }
}

Socket.IO vs WebSocket: When to Use Which

Choose raw WebSocket when you need the lowest possible latency and overhead, your infrastructure fully supports WebSocket, and you do not need automatic reconnection or rooms. This is common for high-frequency trading systems, game servers with custom protocols, or IoT devices with constrained resources.

Choose Socket.IO when you need production-ready features out of the box: automatic reconnection, room-based broadcasting, namespace multiplexing, fallback transports, and binary support. Socket.IO is the better choice for most web applications including chat, notifications, dashboards, and collaborative tools.

Use CaseRecommendedReason
Chat applicationSocket.IORooms, presence, reconnection
Live dashboardSocket.IONamespaces, broadcasting
Multiplayer gameWebSocketMinimal overhead, custom protocol
IoT sensor dataWebSocketLightweight, constrained devices
Collaborative editorSocket.IORooms, acknowledgements
Stock tickerEitherDepends on scale and fallback needs
NotificationsSocket.IOUser rooms, reliable delivery

Frequently Asked Questions

What is Socket.IO and how is it different from WebSocket?

Socket.IO is a library that enables real-time, bidirectional communication between clients and servers. Unlike raw WebSocket, Socket.IO provides automatic reconnection, room-based broadcasting, binary streaming, multiplexing via namespaces, and fallback to HTTP long-polling when WebSocket is unavailable.

Does Socket.IO use WebSocket under the hood?

Yes. Socket.IO uses WebSocket as the primary transport whenever possible. It starts with HTTP long-polling for reliability, then upgrades to WebSocket. You can also configure it to start directly with WebSocket if you know your infrastructure supports it.

How do I scale Socket.IO across multiple servers?

Use the @socket.io/redis-adapter package. It leverages Redis Pub/Sub to broadcast events across all Socket.IO server instances, ensuring messages reach clients connected to any node. You can also use the @socket.io/redis-streams-adapter for ordered delivery.

Can I use Socket.IO with Next.js?

Yes. You can attach a Socket.IO server to the Next.js HTTP server in a custom server file (server.js). For the client side, use the socket.io-client package in your React components. Note that Socket.IO servers cannot run in serverless functions since they require persistent connections.

How do I authenticate Socket.IO connections?

Use Socket.IO middleware to verify JWT tokens or session cookies during the handshake. The client sends the token via the auth option, and the server validates it in an io.use() middleware before allowing the connection to complete.

What is the maximum number of concurrent connections Socket.IO can handle?

A single Socket.IO server can handle roughly 10,000 to 50,000 concurrent connections depending on the hardware and message throughput. With Redis adapter and horizontal scaling, you can handle hundreds of thousands or millions of connections.

How do rooms work in Socket.IO?

Rooms are server-side constructs that allow you to group sockets. A socket can join multiple rooms via socket.join(roomName), and you can broadcast to all sockets in a room via io.to(roomName).emit(). Rooms are automatically cleaned up when sockets disconnect.

How do I handle connection drops and reconnection?

Socket.IO has built-in automatic reconnection with exponential backoff. The client will attempt to reconnect when a connection drops. You can configure reconnection attempts, delay, and backoff via the reconnection, reconnectionAttempts, and reconnectionDelay options.

Conclusion

Socket.IO remains the go-to solution for adding real-time capabilities to Node.js applications. Its event-driven API, built-in room management, automatic reconnection, and seamless scaling via the Redis adapter make it suitable for everything from simple chat apps to complex collaborative platforms. By following the patterns covered in this guide — proper authentication, structured error handling, React hooks integration, and performance optimization — you can build production-grade real-time features with confidence.

For new projects in 2026, Socket.IO v4.x offers connection state recovery, improved TypeScript support, and better performance. Combined with a custom React hook layer and horizontal scaling via Redis, it provides a complete real-time communication stack that is battle-tested by millions of applications worldwide.

𝕏 Twitterin LinkedIn
War das hilfreich?

Bleiben Sie informiert

Wöchentliche Dev-Tipps und neue Tools.

Kein Spam. Jederzeit abbestellbar.

Verwandte Tools ausprobieren

{ }JSON FormatterJSON Validator

Verwandte Artikel

Firebase: Der Komplette Leitfaden für Full-Stack-Apps mit Google

Meistern Sie Firebase mit Authentication, Firestore, Cloud Storage, Functions und Hosting.

WebSocket-Leitfaden: Echtzeit-Kommunikation mit ws und Socket.io

WebSocket-Echtzeit-Kommunikation meistern. Anleitung mit Browser API, Node.js ws, Socket.io, React Hooks, Python websockets und Go gorilla/websocket.

Node.js Leitfaden: Vollständiges Tutorial für Backend-Entwicklung

Node.js Backend meistern. Anleitung mit Event Loop, Express.js, REST APIs, JWT-Auth, DB-Integration, Jest-Tests, PM2-Deployment und Node.js vs Deno vs Bun Vergleich.