{"id":12051,"library":"socketcluster-server","title":"SocketCluster Server","description":"SocketCluster Server (version 20.0.0) is the core server-side module for the SocketCluster real-time framework, designed to facilitate highly scalable, event-driven applications using WebSockets. It operates by attaching to an existing Node.js HTTP/HTTPS server and provides robust mechanisms for managing inbound connections, handling Remote Procedure Calls (RPCs), and processing real-time event streams. A key differentiator and architectural shift in recent major versions is its adoption of modern JavaScript async iterators (`for-await-of` loops) for stream processing, moving away from traditional `EventEmitter` patterns. This paradigm promotes more readable, succinct, and less error-prone code by reducing callback hell and simplifying resource management, as listeners do not need explicit unbinding. While it maintains a compatibility mode for older clients (protocolVersion 1), the current stable version encourages the use of its async iterable API. Releases tend to align with major Node.js LTS updates or significant architectural improvements.","status":"active","version":"20.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/SocketCluster/socketcluster-server","tags":["javascript","websocket","realtime","socketcluster"],"install":[{"cmd":"npm install socketcluster-server","lang":"bash","label":"npm"},{"cmd":"yarn add socketcluster-server","lang":"bash","label":"yarn"},{"cmd":"pnpm add socketcluster-server","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for a full client-server SocketCluster setup and for testing client interactions.","package":"socketcluster-client","optional":false},{"reason":"Required as a base HTTP server to which SocketCluster Server attaches.","package":"http","optional":false},{"reason":"Optional, but commonly used as a base HTTPS server to which SocketCluster Server attaches for secure connections.","package":"https","optional":true}],"imports":[{"note":"Primary CommonJS import. For ESM, use `import * as socketClusterServer from 'socketcluster-server';` as the package exports an object. Direct `import socketClusterServer from 'socketcluster-server';` may not work as expected without a default export.","wrong":"import socketClusterServer from 'socketcluster-server';","symbol":"socketClusterServer","correct":"const socketClusterServer = require('socketcluster-server');"},{"note":"Type import for the `agServer` instance returned by `attach()`. Used for TypeScript type-checking to ensure correct API usage.","wrong":"import { AGServer } from 'socketcluster-server';","symbol":"AGServer","correct":"import type { AGServer } from 'socketcluster-server';"},{"note":"Type import for individual `socket` instances obtained from `agServer.listener('connection')`. Essential for TypeScript type-checking when handling socket events.","wrong":"import { AGSocket } from 'socketcluster-server';","symbol":"AGSocket","correct":"import type { AGSocket } from 'socketcluster-server';"}],"quickstart":{"code":"const http = require('http');\nconst socketClusterServer = require('socketcluster-server');\n\nlet httpServer = http.createServer();\nlet agServer = socketClusterServer.attach(httpServer);\n\n(async () => {\n  // Handle new inbound sockets.\n  for await (let {socket} of agServer.listener('connection')) {\n\n    (async () => {\n      // Set up a loop to handle and respond to RPCs for a procedure.\n      for await (let req of socket.procedure('customProc')) {\n        if (!req.data) {\n          let error = new Error('Server failed to execute the procedure');\n          error.name = 'BadCustomError';\n          req.error(error);\n        } else {\n          req.end('Success');\n        }\n      }\n    })();\n\n    (async () => {\n      // Set up a loop to handle remote transmitted events.\n      for await (let data of socket.receiver('customRemoteEvent')) {\n        console.log(`Received customRemoteEvent: ${data}`);\n      }\n    })();\n\n    socket.transmit('helloClient', { message: 'Hello from server!' });\n  }\n})();\n\nhttpServer.listen(8000, () => {\n  console.log('SocketCluster Server listening on port 8000');\n});","lang":"javascript","description":"Demonstrates how to attach SocketCluster server to an HTTP server and handle inbound connections, RPC procedures, and remote events using async iterators. It also shows transmitting a basic event to connected clients."},"warnings":[{"fix":"Migrate event handling logic to use `for await (const { socket } of agServer.listener('connection'))` and `for await (let req of socket.procedure('procName'))` patterns. Refer to the official v16.x documentation on socketcluster.io.","message":"Upgrading from SocketCluster Server v15.x or earlier to v16.x and above (including v20.0.0) involves a significant API shift from `EventEmitter` patterns to async iterators (`for-await-of` loops). Code relying on `on()`, `addListener()`, or `removeListener()` will need to be refactored.","severity":"breaking","affected_versions":">=16.0.0"},{"fix":"Configure `agServer` attachment with compatibility options: `let agServer = socketClusterServer.attach(httpServer, { protocolVersion: 1, path: '/socketcluster/' });`","message":"To ensure compatibility with older SocketCluster clients (e.g., those using `socketcluster-client` v14.x or earlier), you must explicitly set `protocolVersion: 1` and potentially `path: '/socketcluster/'` during server attachment. Failure to do so will result in client connection errors.","severity":"gotcha","affected_versions":">=16.0.0"},{"fix":"Install both packages: `npm install socketcluster-server socketcluster-client` and refer to `socketcluster-client` documentation for client-side setup.","message":"While `socketcluster-server` can operate independently, a complete real-time application setup typically requires `socketcluster-client` for browser or Node.js clients to connect and interact. For development and testing, both packages are generally needed to form a functional system.","severity":"gotcha","affected_versions":">=16.0.0"},{"fix":"Use a recent LTS version of Node.js (e.g., Node.js 18 or 20) to ensure full compatibility with the async iterator paradigm and performance benefits.","message":"SocketCluster Server heavily leverages modern JavaScript features like `async/await` and `for-await-of` loops. Ensure your Node.js environment is sufficiently recent (e.g., Node.js 12+ for full compatibility) to avoid syntax errors or unexpected behavior.","severity":"gotcha","affected_versions":">=16.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"If running in an ES Module environment (e.g., `\"type\": \"module\"` in `package.json`), change import statements to `import * as socketClusterServer from 'socketcluster-server';` or configure your build tool for CommonJS compatibility.","cause":"Attempting to use CommonJS `require` syntax in an ES Module context without proper configuration.","error":"ReferenceError: require is not defined"},{"fix":"Enable compatibility mode on the server: `socketClusterServer.attach(httpServer, { protocolVersion: 1 });` or update your client to use a compatible `socketcluster-client` version and its default protocol.","cause":"The client is attempting to connect using an older SocketCluster protocol version, but the server is expecting a newer one (or vice-versa).","error":"Client failed to connect: Invalid protocol version"},{"fix":"Ensure `agServer` is correctly created using `socketClusterServer.attach(httpServer);` and that you are using the `listener()` method as shown in the v16+ documentation for async iterators.","cause":"This error likely indicates that `agServer` was not correctly initialized, or an incorrect method name was called, possibly due to an API change in major versions.","error":"TypeError: agServer.listener is not a function"},{"fix":"Change the `httpServer.listen()` port to an available one, or ensure no other applications are using the desired port. On Linux, `lsof -i :8000` can identify the process to terminate.","cause":"The specified port (e.g., 8000) for the HTTP server is already in use by another process or a previous instance of the server was not properly shut down.","error":"Error: listen EADDRINUSE: address already in use :::8000"}],"ecosystem":"npm"}