SockJS-client is a browser JavaScript library that provides a WebSocket-like object for establishing cross-browser, full-duplex communication channels between browsers and web servers.
—
The SockJS class provides the primary interface for establishing and managing WebSocket-like connections with automatic transport fallback capabilities.
Creates a new SockJS connection instance with optional protocol and configuration parameters.
/**
* Creates a new SockJS connection
* @param {string} url - Connection URL (must be http:// or https://)
* @param {string|string[]} [protocols] - Protocol list (reserved parameter, typically not used)
* @param {SockJSOptions} [options] - Configuration options
* @returns {SockJS} SockJS instance
* @throws {TypeError} If url is not provided
* @throws {SyntaxError} If url format is invalid or contains fragments
* @throws {Error} If attempting insecure connection from HTTPS page
*/
function SockJS(url, protocols, options);
// Can be called with or without 'new'
const sock1 = new SockJS('https://example.com/sockjs');
const sock2 = SockJS('https://example.com/sockjs'); // Also validURL Requirements:
#)Protocol Parameter:
Options Object:
interface SockJSOptions {
/** Server identifier appended to connection URL (default: random 4-digit number) */
server?: string;
/** Whitelist of allowed transports (default: all available) */
transports?: string | string[];
/** Session ID generation - number for length or function for custom generator (default: 8) */
sessionId?: number | (() => string);
/** Minimum timeout in milliseconds for transport connections (default: calculated from RTT) */
timeout?: number;
/** Transport-specific configuration options */
transportOptions?: { [transportName: string]: any };
}Usage Examples:
// Basic connection
const sock = new SockJS('https://api.example.com/sockjs');
// With transport restrictions
const sock = new SockJS('https://api.example.com/sockjs', null, {
transports: ['websocket', 'xhr-streaming'],
timeout: 10000
});
// With custom session ID generator
const sock = new SockJS('https://api.example.com/sockjs', null, {
sessionId: () => 'custom-session-' + Date.now()
});
// With server and transport options
const sock = new SockJS('https://api.example.com/sockjs', null, {
server: 'srv001',
transportOptions: {
'xhr-streaming': { timeout: 5000 },
'websocket': { heartbeat: 30000 }
}
});Properties available on SockJS instances for monitoring connection state and configuration.
/**
* The connection URL after parsing and sanitization
* @type {string}
* @readonly
*/
SockJS.prototype.url;
/**
* Current connection state
* @type {number}
* @readonly
* Values: 0 (CONNECTING), 1 (OPEN), 2 (CLOSING), 3 (CLOSED)
*/
SockJS.prototype.readyState;
/**
* WebSocket extensions (always empty string for SockJS)
* @type {string}
* @readonly
*/
SockJS.prototype.extensions;
/**
* Selected protocol (always empty string for SockJS)
* @type {string}
* @readonly
*/
SockJS.prototype.protocol;
/**
* Name of the active transport when connected
* @type {string|null}
* @readonly
* Set to transport name when connection is established, null otherwise
*/
SockJS.prototype.transport;Property Usage Examples:
const sock = new SockJS('https://example.com/sockjs');
// Check connection state
if (sock.readyState === SockJS.CONNECTING) {
console.log('Still connecting...');
}
// Monitor transport selection
sock.onopen = function() {
console.log('Connected using:', sock.transport);
console.log('Final URL:', sock.url);
};Methods for sending data and closing connections.
/**
* Send data through the connection
* @param {any} data - Data to send (converted to string if not already)
* @throws {Error} If connection is not yet established (CONNECTING state)
* @returns {void}
*
* Notes:
* - Non-string data is converted to string via toString()
* - Objects become "[object Object]" unless properly serialized
* - Data is sent only if connection is in OPEN state
* - No-op if connection is CLOSING or CLOSED
*/
SockJS.prototype.send(data);
/**
* Close the connection
* @param {number} [code] - Close code (1000 or 3000-4999, default: 1000)
* @param {string} [reason] - Close reason (max 123 bytes, default: "Normal closure")
* @throws {Error} If code is invalid (not 1000 or outside 3000-4999 range)
* @throws {SyntaxError} If reason exceeds 123 characters
* @returns {void}
*
* Notes:
* - No-op if connection is already CLOSING or CLOSED
* - Triggers 'close' event with wasClean=true
*/
SockJS.prototype.close(code, reason);
/**
* Calculate round-trip timeout based on measured RTT
* @param {number} rtt - Round-trip time in milliseconds
* @returns {number} Calculated timeout value in milliseconds
*
* Note: This is primarily for internal use but exposed as part of the API.
* Used internally to calculate connection timeouts based on network conditions.
* Formula: RTT > 100ms ? 4 * RTT : 300 + RTT
*/
SockJS.prototype.countRTO(rtt);Method Usage Examples:
const sock = new SockJS('https://example.com/sockjs');
sock.onopen = function() {
// Send different data types
sock.send('Hello World'); // String
sock.send(42); // Number -> "42"
sock.send(JSON.stringify({id: 1})); // Proper object serialization
// Close with custom code and reason
setTimeout(() => {
sock.close(1000, 'User requested disconnect');
}, 5000);
};
// Handle send errors
try {
sock.send('data'); // May throw if not connected
} catch (error) {
console.log('Send failed:', error.message);
}
// Advanced: Calculate timeout for given RTT (internal use)
const rtt = 150; // milliseconds
const timeout = sock.countRTO(rtt); // Returns 4 * 150 = 600ms
console.log('Calculated timeout:', timeout);Connection state constants matching WebSocket API.
/**
* Connection state constants
*/
SockJS.CONNECTING = 0; // Connection is being established
SockJS.OPEN = 1; // Connection is open and ready
SockJS.CLOSING = 2; // Connection is being closed
SockJS.CLOSED = 3; // Connection is closed
/**
* Library version string
* @type {string}
*/
SockJS.version; // "1.6.1"Constants Usage:
const sock = new SockJS('https://example.com/sockjs');
// Check connection state using constants
switch (sock.readyState) {
case SockJS.CONNECTING:
console.log('Establishing connection...');
break;
case SockJS.OPEN:
console.log('Connected and ready');
break;
case SockJS.CLOSING:
console.log('Connection closing...');
break;
case SockJS.CLOSED:
console.log('Connection closed');
break;
}
// Check library version
console.log('SockJS version:', SockJS.version);Understanding the connection establishment and teardown process.
Connection Establishment:
CONNECTING (0)OPEN (1), open event firedData Transmission:
readyState === SockJS.OPENConnection Termination:
close() called or transport failure detectedCLOSING (2)CLOSED (3)close event fired with appropriate code and reasonUsage Example - Complete Lifecycle:
const sock = new SockJS('https://example.com/sockjs');
// Monitor state changes
const logState = () => {
const states = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
console.log('State:', states[sock.readyState], 'Transport:', sock.transport);
};
sock.onopen = function() {
logState(); // OPEN, websocket (or other transport)
sock.send('Connected successfully');
};
sock.onmessage = function(e) {
console.log('Received:', e.data);
// Echo back
sock.send('Echo: ' + e.data);
};
sock.onclose = function(e) {
logState(); // CLOSED, null
console.log('Closed:', e.code, e.reason, e.wasClean);
};
sock.onerror = function() {
logState();
console.log('Connection error occurred');
};
// Auto-close after 30 seconds
setTimeout(() => {
if (sock.readyState === SockJS.OPEN) {
sock.close(1000, 'Timeout');
}
}, 30000);The SockJS constructor and methods can throw various errors that should be handled appropriately.
Constructor Errors:
// TypeError: Missing required URL parameter
try {
const sock = new SockJS(); // Throws TypeError
} catch (error) {
console.log('Missing URL:', error.message);
}
// SyntaxError: Invalid URL format
try {
const sock = new SockJS('ftp://invalid.com'); // Throws SyntaxError
} catch (error) {
console.log('Invalid protocol:', error.message);
}
// SyntaxError: URL contains fragment
try {
const sock = new SockJS('https://example.com#fragment'); // Throws SyntaxError
} catch (error) {
console.log('Fragment not allowed:', error.message);
}
// Error: Security violation
try {
// From HTTPS page connecting to HTTP (non-localhost)
const sock = new SockJS('http://example.com/sockjs'); // Throws Error
} catch (error) {
console.log('Security error:', error.message);
}
// TypeError: Invalid sessionId type
try {
const sock = new SockJS('https://example.com', null, {
sessionId: 'invalid' // Must be number or function
}); // Throws TypeError
} catch (error) {
console.log('Invalid sessionId:', error.message);
}Method Errors:
const sock = new SockJS('https://example.com/sockjs');
// send() error
try {
sock.send('data'); // Throws if readyState is CONNECTING
} catch (error) {
console.log('Send failed:', error.message);
}
// close() errors
try {
sock.close(999, 'Invalid code'); // Throws Error for invalid code
} catch (error) {
console.log('Invalid close code:', error.message);
}
try {
sock.close(1000, 'x'.repeat(200)); // Throws SyntaxError if reason too long
} catch (error) {
console.log('Reason too long:', error.message);
}
// Calling close() on already closed connection
sock.close();
sock.close(); // No-op, does not throw errorInstall with Tessl CLI
npx tessl i tessl/npm-sockjs-client