Projekt

Obecné

Profil

Stáhnout (16.4 KB) Statistiky
| Větev: | Revize:
1

    
2
# SockJS-client
3

    
4
[![npm version](https://img.shields.io/npm/v/sockjs-client.svg?style=flat-square)](https://www.npmjs.com/package/sockjs-client)[![Build Status](https://img.shields.io/travis/sockjs/sockjs-client/master.svg?style=flat-square)](https://travis-ci.org/sockjs/sockjs-client)[![Dependencies](https://img.shields.io/david/sockjs/sockjs-client.svg?style=flat-square)](https://david-dm.org/sockjs/sockjs-client)[![Chat](https://img.shields.io/badge/Chat-gitter.im-blue.svg?style=flat-square)](https://gitter.im/sockjs/sockjs-client)
5
[![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=dW9YdlFsSEI5VzNBVVk5ZS9XT0xaTjJVQkhQMkRkNlZBQURiSWNWMC9jaz0tLXRJM05RbW1tTCt5TlhHaVgycFJUYmc9PQ==--e3ef9b9a9fa071084e6d87874b5fc65b71273821)](https://www.browserstack.com/automate/public-build/dW9YdlFsSEI5VzNBVVk5ZS9XT0xaTjJVQkhQMkRkNlZBQURiSWNWMC9jaz0tLXRJM05RbW1tTCt5TlhHaVgycFJUYmc9PQ==--e3ef9b9a9fa071084e6d87874b5fc65b71273821)
6

    
7
# Supporting SockJS
8

    
9
Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools.
10

    
11
[Get supported sockjs-client with the Tidelift Subscription](https://tidelift.com/subscription/pkg/npm-sockjs-client?utm_source=npm-sockjs-client&utm_medium=referral&utm_campaign=readme) 
12

    
13
# Summary
14

    
15
SockJS is a browser JavaScript library that provides a WebSocket-like
16
object. SockJS gives you a coherent, cross-browser, Javascript API
17
which creates a low latency, full duplex, cross-domain communication
18
channel between the browser and the web server.
19

    
20
Under the hood SockJS tries to use native WebSockets first. If that
21
fails it can use a variety of browser-specific transport protocols and
22
presents them through WebSocket-like abstractions.
23

    
24
SockJS is intended to work for all modern browsers and in environments
25
which don't support the WebSocket protocol -- for example, behind restrictive
26
corporate proxies.
27

    
28
SockJS-client does require a server counterpart:
29

    
30
 * [SockJS-node](https://github.com/sockjs/sockjs-node) is a SockJS
31
   server for Node.js.
32

    
33

    
34
Philosophy:
35

    
36
 * The API should follow
37
   [HTML5 Websockets API](https://www.w3.org/TR/websockets/) as
38
   closely as possible.
39
 * All the transports must support cross domain connections out of the
40
   box. It's possible and recommended to host a SockJS server on a
41
   different server than your main web site.
42
 * There is support for at least one streaming protocol for every
43
   major browser.
44
 * Streaming transports should work cross-domain and
45
   should support cookies (for cookie-based sticky sessions).
46
 * Polling transports are used as a fallback for old browsers and
47
   hosts behind restrictive proxies.
48
 * Connection establishment should be fast and lightweight.
49
 * No Flash inside (no need to open port 843 - which doesn't work
50
   through proxies, no need to host 'crossdomain.xml', no need
51
   [to wait for 3 seconds](https://github.com/gimite/web-socket-js/issues/49)
52
   in order to detect problems)
53

    
54

    
55
Subscribe to
56
[SockJS mailing list](https://groups.google.com/forum/#!forum/sockjs) for
57
discussions and support.
58

    
59
# SockJS family
60

    
61
  * [SockJS-client](https://github.com/sockjs/sockjs-client) JavaScript client library
62
  * [SockJS-node](https://github.com/sockjs/sockjs-node) Node.js server
63
  * [SockJS-erlang](https://github.com/sockjs/sockjs-erlang) Erlang server
64
  * [SockJS-cyclone](https://github.com/flaviogrossi/sockjs-cyclone) Python/Cyclone/Twisted server
65
  * [SockJS-tornado](https://github.com/MrJoes/sockjs-tornado) Python/Tornado server
66
  * [SockJS-twisted](https://github.com/DesertBus/sockjs-twisted/) Python/Twisted server
67
  * [SockJS-aiohttp](https://github.com/aio-libs/sockjs/) Python/Aiohttp server
68
  * [Spring Framework](https://projects.spring.io/spring-framework) Java [client](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web.html#websocket-fallback-sockjs-client) & server
69
  * [vert.x](https://github.com/vert-x/vert.x) Java/vert.x server
70
  * [Xitrum](https://xitrum-framework.github.io/) Scala server
71
  * [Atmosphere Framework](https://github.com/Atmosphere/atmosphere) JavaEE Server, Play Framework, Netty, Vert.x
72
  * [Actix SockJS](https://github.com/fafhrd91/actix-sockjs) Rust Server, Actix Framework
73

    
74
Work in progress:
75

    
76
  * [SockJS-ruby](https://github.com/nyarly/sockjs-ruby)
77
  * [SockJS-netty](https://github.com/cgbystrom/sockjs-netty)
78
  * [SockJS-gevent](https://github.com/ksava/sockjs-gevent) ([SockJS-gevent fork](https://github.com/njoyce/sockjs-gevent))
79
  * [pyramid-SockJS](https://github.com/fafhrd91/pyramid_sockjs)
80
  * [wildcloud-websockets](https://github.com/wildcloud/wildcloud-websockets)
81
  * [wai-SockJS](https://github.com/Palmik/wai-sockjs)
82
  * [SockJS-perl](https://github.com/vti/sockjs-perl)
83
  * [SockJS-go](https://github.com/igm/sockjs-go/)
84
  * [syp.biz.SockJS.NET](https://github.com/sypbiz/SockJS.NET) - .NET port of the SockJS client
85

    
86
# Getting Started
87

    
88
SockJS mimics the [WebSockets API](https://www.w3.org/TR/websockets/),
89
but instead of `WebSocket` there is a `SockJS` Javascript object.
90

    
91
First, you need to load the SockJS JavaScript library. For example, you can
92
put that in your HTML head:
93

    
94
```html
95
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
96
```
97

    
98
After the script is loaded you can establish a connection with the
99
SockJS server. Here's a simple example:
100

    
101
```javascript
102
 var sock = new SockJS('https://mydomain.com/my_prefix');
103
 sock.onopen = function() {
104
     console.log('open');
105
     sock.send('test');
106
 };
107

    
108
 sock.onmessage = function(e) {
109
     console.log('message', e.data);
110
     sock.close();
111
 };
112

    
113
 sock.onclose = function() {
114
     console.log('close');
115
 };
116

    
117
```
118

    
119
# SockJS-client API
120

    
121
## SockJS class
122

    
123
Similar to the 'WebSocket' API, the 'SockJS' constructor takes one, or more arguments:
124

    
125
```javascript
126
var sockjs = new SockJS(url, _reserved, options);
127
```
128

    
129
`url` may contain a query string, if one is desired.
130

    
131
Where `options` is a hash which can contain:
132

    
133
 *  **server (string)**
134

    
135
    String to append to url for actual data connection. Defaults to a random 4 digit number.
136

    
137
 *  **transports (string OR array of strings)**
138

    
139
    Sometimes it is useful to disable some fallback transports. This
140
    option allows you to supply a list transports that may be used by
141
    SockJS. By default all available transports will be used.
142

    
143
 *  **sessionId (number OR function)**
144

    
145
    Both client and server use session identifiers to distinguish connections.
146
    If you specify this option as a number, SockJS will use its random string
147
    generator function to generate session ids that are N-character long
148
    (where N corresponds to the number specified by **sessionId**).
149
    When you specify this option as a function, the function must return a
150
    randomly generated string. Every time SockJS needs to generate a session
151
    id it will call this function and use the returned string directly.
152
    If you don't specify this option, the default is to use the default random
153
    string generator to generate 8-character long session ids.
154

    
155
  * **timeout (number)**
156

    
157
    Specify a minimum timeout in milliseconds to use for the transport connections.
158
    By default this is dynamically calculated based on the measured RTT and
159
    the number of expected round trips. This setting will establish a minimum,
160
    but if the calculated timeout is higher, that will be used.
161

    
162
Although the 'SockJS' object tries to emulate the 'WebSocket'
163
behaviour, it's impossible to support all of its features. An
164
important SockJS limitation is the fact that you're not allowed to
165
open more than one SockJS connection to a single domain at a time.
166
This limitation is caused by an in-browser limit of outgoing
167
connections - usually [browsers don't allow opening more than two
168
outgoing connections to a single domain](https://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser). A single SockJS session
169
requires those two connections - one for downloading data, the other for
170
sending messages.  Opening a second SockJS session at the same time
171
would most likely block, and can result in both sessions timing out.
172

    
173
Opening more than one SockJS connection at a time is generally a
174
bad practice. If you absolutely must do it, you can use
175
multiple subdomains, using a different subdomain for every
176
SockJS connection.
177

    
178
# Supported transports, by browser (html served from http:// or https://)
179

    
180
_Browser_       | _Websockets_     | _Streaming_ | _Polling_
181
----------------|------------------|-------------|-------------------
182
IE 6, 7         | no               | no          | jsonp-polling
183
IE 8, 9 (cookies=no) |    no       | xdr-streaming &dagger; | xdr-polling &dagger;
184
IE 8, 9 (cookies=yes)|    no       | iframe-htmlfile | iframe-xhr-polling
185
IE 10           | rfc6455          | xhr-streaming   | xhr-polling
186
Chrome 6-13     | hixie-76         | xhr-streaming   | xhr-polling
187
Chrome 14+      | hybi-10 / rfc6455| xhr-streaming   | xhr-polling
188
Firefox <10     | no &Dagger;      | xhr-streaming   | xhr-polling
189
Firefox 10+     | hybi-10 / rfc6455| xhr-streaming   | xhr-polling
190
Safari 5.x      | hixie-76         | xhr-streaming   | xhr-polling
191
Safari 6+       | rfc6455          | xhr-streaming   | xhr-polling
192
Opera 10.70+    | no &Dagger;      | iframe-eventsource | iframe-xhr-polling
193
Opera 12.10+    | rfc6455          | xhr-streaming | xhr-polling
194
Konqueror       | no               | no          | jsonp-polling
195

    
196

    
197
 * **&dagger;**: IE 8+ supports [XDomainRequest][^9], which is
198
    essentially a modified AJAX/XHR that can do requests across
199
    domains. But unfortunately it doesn't send any cookies, which
200
    makes it inappropriate for deployments when the load balancer uses
201
    JSESSIONID cookie to do sticky sessions.
202

    
203
 * **&Dagger;**: Firefox 4.0 and Opera 11.00 and shipped with disabled
204
     Websockets "hixie-76". They can still be enabled by manually
205
     changing a browser setting.
206

    
207
# Supported transports, by browser (html served from file://)
208

    
209
Sometimes you may want to serve your html from "file://" address - for
210
development or if you're using PhoneGap or similar technologies. But
211
due to the Cross Origin Policy files served from "file://" have no
212
Origin, and that means some of SockJS transports won't work. For this
213
reason the SockJS transport table is different than usually, major
214
differences are:
215

    
216
_Browser_       | _Websockets_  | _Streaming_        | _Polling_
217
----------------|---------------|--------------------|-------------------
218
IE 8, 9         | same as above | iframe-htmlfile    | iframe-xhr-polling
219
Other           | same as above | iframe-eventsource | iframe-xhr-polling
220

    
221
# Supported transports, by name
222

    
223
_Transport_          | _References_
224
---------------------|---------------
225
websocket (rfc6455)  | [rfc 6455][^10]
226
websocket (hixie-76) | [draft-hixie-thewebsocketprotocol-76][^1]
227
websocket (hybi-10)  | [draft-ietf-hybi-thewebsocketprotocol-10][^2]
228
xhr-streaming        | Transport using [Cross domain XHR][^5] [streaming][^7] capability (readyState=3).
229
xdr-streaming        | Transport using [XDomainRequest][^9] [streaming][^7] capability (readyState=3).
230
eventsource          | [EventSource/Server-sent events][^4].
231
iframe-eventsource   | [EventSource/Server-sent events][^4] used from an [iframe via postMessage][^3].
232
htmlfile             | [HtmlFile][^8].
233
iframe-htmlfile      | [HtmlFile][^8] used from an [iframe via postMessage][^3].
234
xhr-polling          | Long-polling using [cross domain XHR][^5].
235
xdr-polling          | Long-polling using [XDomainRequest][^9].
236
iframe-xhr-polling   | Long-polling using normal AJAX from an [iframe via postMessage][^3].
237
jsonp-polling        | Slow and old fashioned [JSONP polling][^6]. This transport will show "busy indicator" (aka: "spinning wheel") when sending data.
238

    
239

    
240
[^1]: https://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
241
[^2]: https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10
242
[^3]: https://developer.mozilla.org/en/DOM/window.postMessage
243
[^4]: https://html.spec.whatwg.org/multipage/comms.html#server-sent-events
244
[^5]: https://secure.wikimedia.org/wikipedia/en/wiki/XMLHttpRequest#Cross-domain_requests
245
[^6]: https://secure.wikimedia.org/wikipedia/en/wiki/JSONP
246
[^7]: http://www.debugtheweb.com/test/teststreaming.aspx
247
[^8]: http://cometdaily.com/2007/11/18/ie-activexhtmlfile-transport-part-ii/
248
[^9]: https://blogs.msdn.microsoft.com/ieinternals/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds/
249
[^10]: https://www.rfc-editor.org/rfc/rfc6455.txt
250

    
251

    
252
# Connecting to SockJS without the client
253

    
254
Although the main point of SockJS is to enable browser-to-server
255
connectivity, it is possible to connect to SockJS from an external
256
application. Any SockJS server complying with 0.3 protocol does
257
support a raw WebSocket url. The raw WebSocket url for the test server
258
looks like:
259

    
260
 * ws://localhost:8081/echo/websocket
261

    
262
You can connect any WebSocket RFC 6455 compliant WebSocket client to
263
this url. This can be a command line client, external application,
264
third party code or even a browser (though I don't know why you would
265
want to do so).
266

    
267

    
268
# Deployment
269

    
270
You should use a version of sockjs-client
271
that supports the protocol used by your server. For example:
272

    
273
```html
274
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
275
```
276

    
277

    
278
For server-side deployment tricks, especially about load balancing and
279
session stickiness, take a look at the
280
[SockJS-node readme](https://github.com/sockjs/sockjs-node#readme).
281

    
282

    
283
# Development and testing
284

    
285
SockJS-client needs [node.js](https://nodejs.org/) for running a test
286
server and JavaScript minification. If you want to work on
287
SockJS-client source code, checkout the git repo and follow these
288
steps:
289

    
290
    cd sockjs-client
291
    npm install
292

    
293
To generate JavaScript, run:
294

    
295
    gulp browserify
296

    
297
To generate minified JavaScript, run:
298

    
299
    gulp browserify:min
300

    
301
Both commands output into the `build` directory.
302

    
303
## Testing
304

    
305
Automated testing provided by:
306

    
307
<a href="https://browserstack.com"><img src="img/Browserstack-logo@2x.png" height="50"></a>
308

    
309
Once you've compiled the SockJS-client you may want to check if your changes
310
pass all the tests.
311

    
312
    npm run test:browser_local
313

    
314
This will start [karma](https://karma-runner.github.io) and a test support server.
315

    
316
# Browser Quirks
317

    
318
There are various browser quirks which we don't intend to address:
319

    
320
 * Pressing ESC in Firefox, before Firefox 20, closes the SockJS connection. For a workaround
321
   and discussion see [#18](https://github.com/sockjs/sockjs-client/issues/18).
322
 * `jsonp-polling` transport will show a "spinning wheel" (aka. "busy indicator")
323
   when sending data.
324
 * You can't open more than one SockJS connection to one domain at the
325
   same time due to [the browser's limit of concurrent connections](https://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser)
326
   (this limit is not counting native WebSocket connections).
327
 * Although SockJS is trying to escape any strange Unicode characters
328
   (even invalid ones - [like surrogates \xD800-\xDBFF](https://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates) or [\xFFFE and \xFFFF](https://en.wikipedia.org/wiki/Unicode#Character_General_Category))
329
   it's advisable to use only valid characters. Using invalid
330
   characters is a bit slower, and may not work with SockJS servers
331
   that have proper Unicode support.
332
 * Having a global function called `onmessage` or such is probably a
333
   bad idea, as it could be called by the built-in `postMessage` API.
334
 * From SockJS' point of view there is nothing special about
335
   SSL/HTTPS. Connecting between unencrypted and encrypted sites
336
   should work just fine.
337
 * Although SockJS does its best to support both prefix and cookie based
338
   sticky sessions, the latter may not work well cross-domain with
339
   browsers that don't accept third-party cookies by default (Safari).
340
   In order to get around this make sure you're connecting to SockJS
341
   from the same parent domain as the main site. For example
342
   'sockjs.a.com' is able to set cookies if you're connecting from
343
   'www.a.com' or 'a.com'.
344
 * Trying to connect from secure "https://" to insecure "http://" is
345
   not a good idea. The other way around should be fine.
346
 * Long polling is known to cause problems on Heroku, but a
347
   [workaround for SockJS is available](https://github.com/sockjs/sockjs-node/issues/57#issuecomment-5242187).
348
 * SockJS [websocket transport is more stable over SSL](https://github.com/sockjs/sockjs-client/issues/94). If
349
   you're a serious SockJS user then consider using SSL
350
   ([more info](https://www.ietf.org/mail-archive/web/hybi/current/msg01605.html)).
(4-4/6)