SocketCluster Client
SocketCluster Client (socketcluster-client) is the JavaScript client library for connecting to SocketCluster servers, enabling high-performance, real-time, bi-directional communication over WebSockets. It provides abstractions for pub/sub (channels), remote procedure calls (RPC), and efficient data streaming. The library is currently at version 20.0.1, indicating an active development cycle with frequent major releases that often introduce breaking changes. Key differentiators include its focus on scalability, built-in support for backpressure handling, and a clear API for consuming events and data streams using async iterators, making it suitable for demanding real-time applications like chat, gaming, and financial dashboards. It is designed to work seamlessly with `socketcluster-server`.
Common errors
-
TypeError: socketCluster.connect is not a function
cause Using the deprecated `connect` method instead of `create`.fixChange `socketClusterClient.connect(...)` to `socketClusterClient.create(...)`. The `connect` method was renamed in v10.0.0. -
ReferenceError: socketClusterClient is not defined
cause The `socketcluster-client` script tag was not loaded in the HTML, or the module was not correctly imported/required in a module environment.fixEnsure `<script type="text/javascript" src="/socketcluster-client.js"></script>` is present and accessible in your HTML, or use `import { create } from 'socketcluster-client';` (ESM) / `const { create } = require('socketcluster-client');` (CJS) at the top of your JavaScript file. -
Error: Cannot read properties of undefined (reading 'connections')
cause Attempting to access `socketCluster.connections` which was renamed.fixUpdate code to use `socketCluster.clients` instead of `socketCluster.connections`. This rename occurred in v10.0.0. -
UnhandledPromiseRejectionWarning: Error: Socket emitted a reserved event
cause The client attempted to emit an event name that is reserved by SocketCluster internally.fixRename the custom event you are trying to transmit to avoid conflict with SocketCluster's internal event names. This behavior changed in v13.0.0.
Warnings
- breaking The `SCSocket` class was renamed to `SCClientSocket` for better clarity and consistency with server-side naming conventions.
- breaking The 'authenticate' event now triggers whenever the `authToken` changes, not just on the initial authentication. This affects scenarios where a new user's token might override a previously logged-in user's token on the same client instance.
- breaking The `socketCluster.connect(options)` method was renamed to `socketCluster.create(options)`. The `connect` alias is deprecated but still available.
- breaking The `socketCluster.connections` object/map was renamed to `socketCluster.clients`.
- gotcha Passing invalid combinations of `hostname`, `host`, and `port` arguments to `create()` will now throw an error, enforcing stricter configuration validation.
- gotcha Attempting to emit a reserved event on the socket will now cause an error to be emitted on the socket itself. This prevents potential conflicts with internal SocketCluster protocols.
Install
-
npm install socketcluster-client -
yarn add socketcluster-client -
pnpm add socketcluster-client
Imports
- create
import socketClusterClient from 'socketcluster-client'; const socket = socketClusterClient.create(...);
import { create } from 'socketcluster-client'; - SCClientSocket
import { SCSocket } from 'socketcluster-client';import { SCClientSocket } from 'socketcluster-client'; - socketClusterClient (global/module object)
import socketClusterClient from 'socketcluster-client'; // Potentially not the default export, depending on bundler config.
const socketClusterClient = require('socketcluster-client'); // CommonJS // Or in browser after script tag: const socket = socketClusterClient.create(...);
Quickstart
import { create } from 'socketcluster-client';
const socket = create({
hostname: 'localhost',
port: 8000,
autoConnect: true,
autoReconnectOptions: {
initialDelay: 1000,
randomness: 500,
multiplier: 1.2,
maxDelay: 10000
}
});
(async () => {
try {
await socket.listener('connect').once();
console.log('Socket connected successfully to server.');
// Transmit data to the server without expecting a response
socket.transmit('chatMessage', { user: 'developer', text: 'Hello SocketCluster!' });
// Invoke a remote procedure call (RPC) and await a response
const serverTime = await socket.invoke('getServerTime');
console.log('Server time received:', serverTime);
// Subscribe to a channel and consume messages
const myChannel = socket.subscribe('myPublicChannel');
await myChannel.listener('subscribe').once();
console.log('Successfully subscribed to channel: myPublicChannel');
// Publish a message to the channel
await myChannel.invokePublish('This is a message from the client.');
console.log('Published message to channel.');
// Consume messages from the channel using an async iterator
for await (const data of myChannel) {
console.log('Received channel message:', data);
// For demonstration, process one message then unsubscribe
break;
}
myChannel.unsubscribe();
console.log('Unsubscribed from channel.');
} catch (error) {
console.error('Socket error or connection failed:', error);
}
// Disconnect the socket after a short delay
setTimeout(() => {
socket.disconnect();
console.log('Socket disconnected.');
}, 5000);
})();