MessageBus JavaScript Client
The `message-bus-client` package is the official JavaScript client library for connecting to the Ruby `message_bus` server. It provides robust functionalities for subscribing to channels, receiving real-time messages via polling, long-polling, or long-polling with streaming, and managing subscriptions and message backlogs. Designed to work seamlessly with the `message_bus` Ruby gem, which acts as a Rack middleware, it enables scalable concurrent connections. The current stable version is 4.5.2, reflecting active maintenance, as it is a critical component of Discourse, where it's used in production at scale. Its primary role is to establish a reliable client-server communication channel for web applications.
Common errors
-
GET http://your-messagebus-server.com/message-bus/poll net::ERR_CONNECTION_REFUSED
cause The MessageBus server is not running, is inaccessible at the specified URL, or a firewall is blocking the connection.fixVerify that your MessageBus server (Ruby application) is actively running and reachable from the client's network. Check server logs for startup errors and ensure the `baseUrl` configured in the client matches the server's address. -
Access to fetch at 'http://your-messagebus-server.com/message-bus/poll' from origin 'http://your-client-domain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
cause The browser is enforcing its Same-Origin Policy, and the MessageBus server has not sent the necessary `Access-Control-Allow-Origin` header allowing requests from your client's domain.fixOn the MessageBus server, configure CORS to allow requests from your client's domain (e.g., `http://your-client-domain.com`). This typically involves adding middleware like `rack-cors` in Ruby Rack applications. -
TypeError: MessageBus is not a constructor
cause This error occurs when attempting to invoke `MessageBus` as a function instead of instantiating it as a class using the `new` keyword.fixEnsure that `MessageBus` is instantiated correctly with `new`: `const bus = new MessageBus();`.
Warnings
- breaking The upstream MessageBus Ruby gem (server-side component) officially supports Ruby versions 3.2 and up as of March 2025. Running the server with older, unsupported Ruby versions may lead to compatibility issues or unexpected behavior with the JavaScript client.
- gotcha Optimal performance and concurrent long-polling for the MessageBus server (Ruby gem) heavily rely on specific Rack middleware and web server configurations (e.g., Rack Hijack, Thin::Async). Improper server setup can significantly degrade performance or cause connection instability for clients.
- gotcha Significant version discrepancies between the `message-bus-client` and the `message_bus` Ruby gem can lead to unexpected behavior, connection failures, or protocol mismatches. It is generally recommended to keep both components updated to compatible versions.
- gotcha If the `message-bus-client` is deployed on a different domain or port than the `message_bus` server, Cross-Origin Resource Sharing (CORS) headers must be properly configured on the server. Failure to do so will result in browser security errors blocking client-server communication.
Install
-
npm install message-bus-client -
yarn add message-bus-client -
pnpm add message-bus-client
Imports
- MessageBus
import MessageBus from 'message-bus-client';
import { MessageBus } from 'message-bus-client'; - MessageBus
const MessageBus = require('message-bus-client');const { MessageBus } = require('message-bus-client'); - MessageBusOptions
import { MessageBusOptions } from 'message-bus-client';import type { MessageBusOptions } from 'message-bus-client';
Quickstart
import { MessageBus } from 'message-bus-client';
// Configure the MessageBus client with your server's base URL if different from current origin
const bus = new MessageBus({
baseUrl: 'http://localhost:9292/message-bus' // Replace with your MessageBus server URL
});
bus.start(); // Start polling for messages immediately
bus.subscribe('/global-channel', (data, messageId) => {
console.log(`Received message on /global-channel (ID: ${messageId}):`, data);
});
bus.subscribe('/user-channel-123', (data) => {
console.log('Received targeted message:', data);
});
// To stop listening and disconnect
// setTimeout(() => {
// bus.unsubscribe('/global-channel');
// bus.stop();
// console.log('MessageBus stopped and unsubscribed.');
// }, 60000);