0
# Core Connection API
1
2
The SockJS class provides the primary interface for establishing and managing WebSocket-like connections with automatic transport fallback capabilities.
3
4
## Capabilities
5
6
### SockJS Constructor
7
8
Creates a new SockJS connection instance with optional protocol and configuration parameters.
9
10
```javascript { .api }
11
/**
12
* Creates a new SockJS connection
13
* @param {string} url - Connection URL (must be http:// or https://)
14
* @param {string|string[]} [protocols] - Protocol list (reserved parameter, typically not used)
15
* @param {SockJSOptions} [options] - Configuration options
16
* @returns {SockJS} SockJS instance
17
* @throws {TypeError} If url is not provided
18
* @throws {SyntaxError} If url format is invalid or contains fragments
19
* @throws {Error} If attempting insecure connection from HTTPS page
20
*/
21
function SockJS(url, protocols, options);
22
23
// Can be called with or without 'new'
24
const sock1 = new SockJS('https://example.com/sockjs');
25
const sock2 = SockJS('https://example.com/sockjs'); // Also valid
26
```
27
28
**URL Requirements:**
29
- Must be a valid HTTP or HTTPS URL
30
- Cannot contain URL fragments (`#`)
31
- Query parameters are allowed and preserved
32
- Cross-domain URLs are supported with proper server configuration
33
34
**Protocol Parameter:**
35
- Second parameter is reserved and typically not used
36
- Can be string or array of strings
37
- Must not contain empty strings or duplicates
38
- Used for WebSocket protocol compatibility but has no effect in SockJS
39
40
**Options Object:**
41
42
```javascript { .api }
43
interface SockJSOptions {
44
/** Server identifier appended to connection URL (default: random 4-digit number) */
45
server?: string;
46
47
/** Whitelist of allowed transports (default: all available) */
48
transports?: string | string[];
49
50
/** Session ID generation - number for length or function for custom generator (default: 8) */
51
sessionId?: number | (() => string);
52
53
/** Minimum timeout in milliseconds for transport connections (default: calculated from RTT) */
54
timeout?: number;
55
56
/** Transport-specific configuration options */
57
transportOptions?: { [transportName: string]: any };
58
}
59
```
60
61
**Usage Examples:**
62
63
```javascript
64
// Basic connection
65
const sock = new SockJS('https://api.example.com/sockjs');
66
67
// With transport restrictions
68
const sock = new SockJS('https://api.example.com/sockjs', null, {
69
transports: ['websocket', 'xhr-streaming'],
70
timeout: 10000
71
});
72
73
// With custom session ID generator
74
const sock = new SockJS('https://api.example.com/sockjs', null, {
75
sessionId: () => 'custom-session-' + Date.now()
76
});
77
78
// With server and transport options
79
const sock = new SockJS('https://api.example.com/sockjs', null, {
80
server: 'srv001',
81
transportOptions: {
82
'xhr-streaming': { timeout: 5000 },
83
'websocket': { heartbeat: 30000 }
84
}
85
});
86
```
87
88
### Instance Properties
89
90
Properties available on SockJS instances for monitoring connection state and configuration.
91
92
```javascript { .api }
93
/**
94
* The connection URL after parsing and sanitization
95
* @type {string}
96
* @readonly
97
*/
98
SockJS.prototype.url;
99
100
/**
101
* Current connection state
102
* @type {number}
103
* @readonly
104
* Values: 0 (CONNECTING), 1 (OPEN), 2 (CLOSING), 3 (CLOSED)
105
*/
106
SockJS.prototype.readyState;
107
108
/**
109
* WebSocket extensions (always empty string for SockJS)
110
* @type {string}
111
* @readonly
112
*/
113
SockJS.prototype.extensions;
114
115
/**
116
* Selected protocol (always empty string for SockJS)
117
* @type {string}
118
* @readonly
119
*/
120
SockJS.prototype.protocol;
121
122
/**
123
* Name of the active transport when connected
124
* @type {string|null}
125
* @readonly
126
* Set to transport name when connection is established, null otherwise
127
*/
128
SockJS.prototype.transport;
129
```
130
131
**Property Usage Examples:**
132
133
```javascript
134
const sock = new SockJS('https://example.com/sockjs');
135
136
// Check connection state
137
if (sock.readyState === SockJS.CONNECTING) {
138
console.log('Still connecting...');
139
}
140
141
// Monitor transport selection
142
sock.onopen = function() {
143
console.log('Connected using:', sock.transport);
144
console.log('Final URL:', sock.url);
145
};
146
```
147
148
### Instance Methods
149
150
Methods for sending data and closing connections.
151
152
```javascript { .api }
153
/**
154
* Send data through the connection
155
* @param {any} data - Data to send (converted to string if not already)
156
* @throws {Error} If connection is not yet established (CONNECTING state)
157
* @returns {void}
158
*
159
* Notes:
160
* - Non-string data is converted to string via toString()
161
* - Objects become "[object Object]" unless properly serialized
162
* - Data is sent only if connection is in OPEN state
163
* - No-op if connection is CLOSING or CLOSED
164
*/
165
SockJS.prototype.send(data);
166
167
/**
168
* Close the connection
169
* @param {number} [code] - Close code (1000 or 3000-4999, default: 1000)
170
* @param {string} [reason] - Close reason (max 123 bytes, default: "Normal closure")
171
* @throws {Error} If code is invalid (not 1000 or outside 3000-4999 range)
172
* @throws {SyntaxError} If reason exceeds 123 characters
173
* @returns {void}
174
*
175
* Notes:
176
* - No-op if connection is already CLOSING or CLOSED
177
* - Triggers 'close' event with wasClean=true
178
*/
179
SockJS.prototype.close(code, reason);
180
181
/**
182
* Calculate round-trip timeout based on measured RTT
183
* @param {number} rtt - Round-trip time in milliseconds
184
* @returns {number} Calculated timeout value in milliseconds
185
*
186
* Note: This is primarily for internal use but exposed as part of the API.
187
* Used internally to calculate connection timeouts based on network conditions.
188
* Formula: RTT > 100ms ? 4 * RTT : 300 + RTT
189
*/
190
SockJS.prototype.countRTO(rtt);
191
```
192
193
**Method Usage Examples:**
194
195
```javascript
196
const sock = new SockJS('https://example.com/sockjs');
197
198
sock.onopen = function() {
199
// Send different data types
200
sock.send('Hello World'); // String
201
sock.send(42); // Number -> "42"
202
sock.send(JSON.stringify({id: 1})); // Proper object serialization
203
204
// Close with custom code and reason
205
setTimeout(() => {
206
sock.close(1000, 'User requested disconnect');
207
}, 5000);
208
};
209
210
// Handle send errors
211
try {
212
sock.send('data'); // May throw if not connected
213
} catch (error) {
214
console.log('Send failed:', error.message);
215
}
216
217
// Advanced: Calculate timeout for given RTT (internal use)
218
const rtt = 150; // milliseconds
219
const timeout = sock.countRTO(rtt); // Returns 4 * 150 = 600ms
220
console.log('Calculated timeout:', timeout);
221
```
222
223
### Static Constants
224
225
Connection state constants matching WebSocket API.
226
227
```javascript { .api }
228
/**
229
* Connection state constants
230
*/
231
SockJS.CONNECTING = 0; // Connection is being established
232
SockJS.OPEN = 1; // Connection is open and ready
233
SockJS.CLOSING = 2; // Connection is being closed
234
SockJS.CLOSED = 3; // Connection is closed
235
236
/**
237
* Library version string
238
* @type {string}
239
*/
240
SockJS.version; // "1.6.1"
241
```
242
243
**Constants Usage:**
244
245
```javascript
246
const sock = new SockJS('https://example.com/sockjs');
247
248
// Check connection state using constants
249
switch (sock.readyState) {
250
case SockJS.CONNECTING:
251
console.log('Establishing connection...');
252
break;
253
case SockJS.OPEN:
254
console.log('Connected and ready');
255
break;
256
case SockJS.CLOSING:
257
console.log('Connection closing...');
258
break;
259
case SockJS.CLOSED:
260
console.log('Connection closed');
261
break;
262
}
263
264
// Check library version
265
console.log('SockJS version:', SockJS.version);
266
```
267
268
### Connection Lifecycle
269
270
Understanding the connection establishment and teardown process.
271
272
**Connection Establishment:**
273
274
1. Constructor validates URL and options
275
2. Connection state set to `CONNECTING` (0)
276
3. Server info retrieval begins
277
4. Transport selection based on capabilities and whitelist
278
5. Transport connection attempt with timeout
279
6. On success: state becomes `OPEN` (1), `open` event fired
280
7. On failure: fallback to next transport or connection failure
281
282
**Data Transmission:**
283
284
- Only possible when `readyState === SockJS.OPEN`
285
- All data converted to strings before transmission
286
- Messages queued internally if transport is temporarily unavailable
287
288
**Connection Termination:**
289
290
1. `close()` called or transport failure detected
291
2. State becomes `CLOSING` (2)
292
3. Transport cleanup initiated
293
4. State becomes `CLOSED` (3)
294
5. `close` event fired with appropriate code and reason
295
296
**Usage Example - Complete Lifecycle:**
297
298
```javascript
299
const sock = new SockJS('https://example.com/sockjs');
300
301
// Monitor state changes
302
const logState = () => {
303
const states = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
304
console.log('State:', states[sock.readyState], 'Transport:', sock.transport);
305
};
306
307
sock.onopen = function() {
308
logState(); // OPEN, websocket (or other transport)
309
sock.send('Connected successfully');
310
};
311
312
sock.onmessage = function(e) {
313
console.log('Received:', e.data);
314
// Echo back
315
sock.send('Echo: ' + e.data);
316
};
317
318
sock.onclose = function(e) {
319
logState(); // CLOSED, null
320
console.log('Closed:', e.code, e.reason, e.wasClean);
321
};
322
323
sock.onerror = function() {
324
logState();
325
console.log('Connection error occurred');
326
};
327
328
// Auto-close after 30 seconds
329
setTimeout(() => {
330
if (sock.readyState === SockJS.OPEN) {
331
sock.close(1000, 'Timeout');
332
}
333
}, 30000);
334
```
335
336
## Error Handling
337
338
The SockJS constructor and methods can throw various errors that should be handled appropriately.
339
340
**Constructor Errors:**
341
342
```javascript { .api }
343
// TypeError: Missing required URL parameter
344
try {
345
const sock = new SockJS(); // Throws TypeError
346
} catch (error) {
347
console.log('Missing URL:', error.message);
348
}
349
350
// SyntaxError: Invalid URL format
351
try {
352
const sock = new SockJS('ftp://invalid.com'); // Throws SyntaxError
353
} catch (error) {
354
console.log('Invalid protocol:', error.message);
355
}
356
357
// SyntaxError: URL contains fragment
358
try {
359
const sock = new SockJS('https://example.com#fragment'); // Throws SyntaxError
360
} catch (error) {
361
console.log('Fragment not allowed:', error.message);
362
}
363
364
// Error: Security violation
365
try {
366
// From HTTPS page connecting to HTTP (non-localhost)
367
const sock = new SockJS('http://example.com/sockjs'); // Throws Error
368
} catch (error) {
369
console.log('Security error:', error.message);
370
}
371
372
// TypeError: Invalid sessionId type
373
try {
374
const sock = new SockJS('https://example.com', null, {
375
sessionId: 'invalid' // Must be number or function
376
}); // Throws TypeError
377
} catch (error) {
378
console.log('Invalid sessionId:', error.message);
379
}
380
```
381
382
**Method Errors:**
383
384
```javascript { .api }
385
const sock = new SockJS('https://example.com/sockjs');
386
387
// send() error
388
try {
389
sock.send('data'); // Throws if readyState is CONNECTING
390
} catch (error) {
391
console.log('Send failed:', error.message);
392
}
393
394
// close() errors
395
try {
396
sock.close(999, 'Invalid code'); // Throws Error for invalid code
397
} catch (error) {
398
console.log('Invalid close code:', error.message);
399
}
400
401
try {
402
sock.close(1000, 'x'.repeat(200)); // Throws SyntaxError if reason too long
403
} catch (error) {
404
console.log('Reason too long:', error.message);
405
}
406
407
// Calling close() on already closed connection
408
sock.close();
409
sock.close(); // No-op, does not throw error
410
```