Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. # SockJS-client
  2. [![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)
  3. [![Sauce Test Status](https://saucelabs.com/buildstatus/brycekahle)](https://saucelabs.com/u/brycekahle)
  4. SockJS is a browser JavaScript library that provides a WebSocket-like
  5. object. SockJS gives you a coherent, cross-browser, Javascript API
  6. which creates a low latency, full duplex, cross-domain communication
  7. channel between the browser and the web server.
  8. Under the hood SockJS tries to use native WebSockets first. If that
  9. fails it can use a variety of browser-specific transport protocols and
  10. presents them through WebSocket-like abstractions.
  11. SockJS is intended to work for all modern browsers and in environments
  12. which don't support the WebSocket protocol -- for example, behind restrictive
  13. corporate proxies.
  14. SockJS-client does require a server counterpart:
  15. * [SockJS-node](https://github.com/sockjs/sockjs-node) is a SockJS
  16. server for Node.js.
  17. Philosophy:
  18. * The API should follow
  19. [HTML5 Websockets API](https://www.w3.org/TR/websockets/) as
  20. closely as possible.
  21. * All the transports must support cross domain connections out of the
  22. box. It's possible and recommended to host a SockJS server on a
  23. different server than your main web site.
  24. * There is support for at least one streaming protocol for every
  25. major browser.
  26. * Streaming transports should work cross-domain and
  27. should support cookies (for cookie-based sticky sessions).
  28. * Polling transports are used as a fallback for old browsers and
  29. hosts behind restrictive proxies.
  30. * Connection establishment should be fast and lightweight.
  31. * No Flash inside (no need to open port 843 - which doesn't work
  32. through proxies, no need to host 'crossdomain.xml', no need
  33. [to wait for 3 seconds](https://github.com/gimite/web-socket-js/issues/49)
  34. in order to detect problems)
  35. Subscribe to
  36. [SockJS mailing list](https://groups.google.com/forum/#!forum/sockjs) for
  37. discussions and support.
  38. SockJS family:
  39. * [SockJS-client](https://github.com/sockjs/sockjs-client) JavaScript client library
  40. * [SockJS-node](https://github.com/sockjs/sockjs-node) Node.js server
  41. * [SockJS-erlang](https://github.com/sockjs/sockjs-erlang) Erlang server
  42. * [SockJS-cyclone](https://github.com/flaviogrossi/sockjs-cyclone) Python/Cyclone/Twisted server
  43. * [SockJS-tornado](https://github.com/MrJoes/sockjs-tornado) Python/Tornado server
  44. * [SockJS-twisted](https://github.com/DesertBus/sockjs-twisted/) Python/Twisted server
  45. * [SockJS-aiohttp](https://github.com/aio-libs/sockjs/) Python/Aiohttp server
  46. * [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
  47. * [vert.x](https://github.com/vert-x/vert.x) Java/vert.x server
  48. * [Xitrum](https://xitrum-framework.github.io/) Scala server
  49. * [Atmosphere Framework](https://github.com/Atmosphere/atmosphere) JavaEE Server, Play Framework, Netty, Vert.x
  50. * [Actix SockJS](https://github.com/fafhrd91/actix-sockjs) Rust Server, Actix Framework
  51. Work in progress:
  52. * [SockJS-ruby](https://github.com/nyarly/sockjs-ruby)
  53. * [SockJS-netty](https://github.com/cgbystrom/sockjs-netty)
  54. * [SockJS-gevent](https://github.com/ksava/sockjs-gevent) ([SockJS-gevent fork](https://github.com/njoyce/sockjs-gevent))
  55. * [pyramid-SockJS](https://github.com/fafhrd91/pyramid_sockjs)
  56. * [wildcloud-websockets](https://github.com/wildcloud/wildcloud-websockets)
  57. * [wai-SockJS](https://github.com/Palmik/wai-sockjs)
  58. * [SockJS-perl](https://github.com/vti/sockjs-perl)
  59. * [SockJS-go](https://github.com/igm/sockjs-go/)
  60. Getting Started
  61. -------
  62. SockJS mimics the [WebSockets API](https://www.w3.org/TR/websockets/),
  63. but instead of `WebSocket` there is a `SockJS` Javascript object.
  64. First, you need to load the SockJS JavaScript library. For example, you can
  65. put that in your HTML head:
  66. ```html
  67. <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
  68. ```
  69. After the script is loaded you can establish a connection with the
  70. SockJS server. Here's a simple example:
  71. ```javascript
  72. var sock = new SockJS('https://mydomain.com/my_prefix');
  73. sock.onopen = function() {
  74. console.log('open');
  75. sock.send('test');
  76. };
  77. sock.onmessage = function(e) {
  78. console.log('message', e.data);
  79. sock.close();
  80. };
  81. sock.onclose = function() {
  82. console.log('close');
  83. };
  84. ```
  85. SockJS-client API
  86. -----------------
  87. ### SockJS class
  88. Similar to the 'WebSocket' API, the 'SockJS' constructor takes one, or more arguments:
  89. ```javascript
  90. var sockjs = new SockJS(url, _reserved, options);
  91. ```
  92. `url` may contain a query string, if one is desired.
  93. Where `options` is a hash which can contain:
  94. * **server (string)**
  95. String to append to url for actual data connection. Defaults to a random 4 digit number.
  96. * **transports (string OR array of strings)**
  97. Sometimes it is useful to disable some fallback transports. This
  98. option allows you to supply a list transports that may be used by
  99. SockJS. By default all available transports will be used.
  100. * **sessionId (number OR function)**
  101. Both client and server use session identifiers to distinguish connections.
  102. If you specify this option as a number, SockJS will use its random string
  103. generator function to generate session ids that are N-character long
  104. (where N corresponds to the number specified by **sessionId**).
  105. When you specify this option as a function, the function must return a
  106. randomly generated string. Every time SockJS needs to generate a session
  107. id it will call this function and use the returned string directly.
  108. If you don't specify this option, the default is to use the default random
  109. string generator to generate 8-character long session ids.
  110. Although the 'SockJS' object tries to emulate the 'WebSocket'
  111. behaviour, it's impossible to support all of its features. An
  112. important SockJS limitation is the fact that you're not allowed to
  113. open more than one SockJS connection to a single domain at a time.
  114. This limitation is caused by an in-browser limit of outgoing
  115. connections - usually [browsers don't allow opening more than two
  116. outgoing connections to a single domain](https://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser). A single SockJS session
  117. requires those two connections - one for downloading data, the other for
  118. sending messages. Opening a second SockJS session at the same time
  119. would most likely block, and can result in both sessions timing out.
  120. Opening more than one SockJS connection at a time is generally a
  121. bad practice. If you absolutely must do it, you can use
  122. multiple subdomains, using a different subdomain for every
  123. SockJS connection.
  124. Supported transports, by browser (html served from http:// or https://)
  125. -----------------------------------------------------------------------
  126. _Browser_ | _Websockets_ | _Streaming_ | _Polling_
  127. ----------------|------------------|-------------|-------------------
  128. IE 6, 7 | no | no | jsonp-polling
  129. IE 8, 9 (cookies=no) | no | xdr-streaming &dagger; | xdr-polling &dagger;
  130. IE 8, 9 (cookies=yes)| no | iframe-htmlfile | iframe-xhr-polling
  131. IE 10 | rfc6455 | xhr-streaming | xhr-polling
  132. Chrome 6-13 | hixie-76 | xhr-streaming | xhr-polling
  133. Chrome 14+ | hybi-10 / rfc6455| xhr-streaming | xhr-polling
  134. Firefox <10 | no &Dagger; | xhr-streaming | xhr-polling
  135. Firefox 10+ | hybi-10 / rfc6455| xhr-streaming | xhr-polling
  136. Safari 5.x | hixie-76 | xhr-streaming | xhr-polling
  137. Safari 6+ | rfc6455 | xhr-streaming | xhr-polling
  138. Opera 10.70+ | no &Dagger; | iframe-eventsource | iframe-xhr-polling
  139. Opera 12.10+ | rfc6455 | xhr-streaming | xhr-polling
  140. Konqueror | no | no | jsonp-polling
  141. * **&dagger;**: IE 8+ supports [XDomainRequest][^9], which is
  142. essentially a modified AJAX/XHR that can do requests across
  143. domains. But unfortunately it doesn't send any cookies, which
  144. makes it inappropriate for deployments when the load balancer uses
  145. JSESSIONID cookie to do sticky sessions.
  146. * **&Dagger;**: Firefox 4.0 and Opera 11.00 and shipped with disabled
  147. Websockets "hixie-76". They can still be enabled by manually
  148. changing a browser setting.
  149. Supported transports, by browser (html served from file://)
  150. -----------------------------------------------------------
  151. Sometimes you may want to serve your html from "file://" address - for
  152. development or if you're using PhoneGap or similar technologies. But
  153. due to the Cross Origin Policy files served from "file://" have no
  154. Origin, and that means some of SockJS transports won't work. For this
  155. reason the SockJS transport table is different than usually, major
  156. differences are:
  157. _Browser_ | _Websockets_ | _Streaming_ | _Polling_
  158. ----------------|---------------|--------------------|-------------------
  159. IE 8, 9 | same as above | iframe-htmlfile | iframe-xhr-polling
  160. Other | same as above | iframe-eventsource | iframe-xhr-polling
  161. Supported transports, by name
  162. -----------------------------
  163. _Transport_ | _References_
  164. ---------------------|---------------
  165. websocket (rfc6455) | [rfc 6455][^10]
  166. websocket (hixie-76) | [draft-hixie-thewebsocketprotocol-76][^1]
  167. websocket (hybi-10) | [draft-ietf-hybi-thewebsocketprotocol-10][^2]
  168. xhr-streaming | Transport using [Cross domain XHR][^5] [streaming][^7] capability (readyState=3).
  169. xdr-streaming | Transport using [XDomainRequest][^9] [streaming][^7] capability (readyState=3).
  170. eventsource | [EventSource/Server-sent events][^4].
  171. iframe-eventsource | [EventSource/Server-sent events][^4] used from an [iframe via postMessage][^3].
  172. htmlfile | [HtmlFile][^8].
  173. iframe-htmlfile | [HtmlFile][^8] used from an [iframe via postMessage][^3].
  174. xhr-polling | Long-polling using [cross domain XHR][^5].
  175. xdr-polling | Long-polling using [XDomainRequest][^9].
  176. iframe-xhr-polling | Long-polling using normal AJAX from an [iframe via postMessage][^3].
  177. jsonp-polling | Slow and old fashioned [JSONP polling][^6]. This transport will show "busy indicator" (aka: "spinning wheel") when sending data.
  178. [^1]: https://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
  179. [^2]: https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10
  180. [^3]: https://developer.mozilla.org/en/DOM/window.postMessage
  181. [^4]: https://html.spec.whatwg.org/multipage/comms.html#server-sent-events
  182. [^5]: https://secure.wikimedia.org/wikipedia/en/wiki/XMLHttpRequest#Cross-domain_requests
  183. [^6]: https://secure.wikimedia.org/wikipedia/en/wiki/JSONP
  184. [^7]: http://www.debugtheweb.com/test/teststreaming.aspx
  185. [^8]: http://cometdaily.com/2007/11/18/ie-activexhtmlfile-transport-part-ii/
  186. [^9]: https://blogs.msdn.microsoft.com/ieinternals/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds/
  187. [^10]: https://www.rfc-editor.org/rfc/rfc6455.txt
  188. Connecting to SockJS without the client
  189. ---------------------------------------
  190. Although the main point of SockJS is to enable browser-to-server
  191. connectivity, it is possible to connect to SockJS from an external
  192. application. Any SockJS server complying with 0.3 protocol does
  193. support a raw WebSocket url. The raw WebSocket url for the test server
  194. looks like:
  195. * ws://localhost:8081/echo/websocket
  196. You can connect any WebSocket RFC 6455 compliant WebSocket client to
  197. this url. This can be a command line client, external application,
  198. third party code or even a browser (though I don't know why you would
  199. want to do so).
  200. Deployment
  201. ----------
  202. You should use a version of sockjs-client
  203. that supports the protocol used by your server. For example:
  204. ```html
  205. <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
  206. ```
  207. For server-side deployment tricks, especially about load balancing and
  208. session stickiness, take a look at the
  209. [SockJS-node readme](https://github.com/sockjs/sockjs-node#readme).
  210. Development and testing
  211. -----------------------
  212. SockJS-client needs [node.js](https://nodejs.org/) for running a test
  213. server and JavaScript minification. If you want to work on
  214. SockJS-client source code, checkout the git repo and follow these
  215. steps:
  216. cd sockjs-client
  217. npm install
  218. To generate JavaScript, run:
  219. gulp browserify
  220. To generate minified JavaScript, run:
  221. gulp browserify:min
  222. Both commands output into the `build` directory.
  223. ### Testing
  224. Once you've compiled the SockJS-client you may want to check if your changes
  225. pass all the tests.
  226. npm run test:browser_local
  227. This will start [zuul](https://github.com/defunctzombie/zuul) and a test support server. Open the browser to [http://localhost:9090/_zuul](http://localhost:9090/_zuul) and watch the tests run.
  228. Browser Quirks
  229. --------------
  230. There are various browser quirks which we don't intend to address:
  231. * Pressing ESC in Firefox, before Firefox 20, closes the SockJS connection. For a workaround
  232. and discussion see [#18](https://github.com/sockjs/sockjs-client/issues/18).
  233. * `jsonp-polling` transport will show a "spinning wheel" (aka. "busy indicator")
  234. when sending data.
  235. * You can't open more than one SockJS connection to one domain at the
  236. same time due to [the browser's limit of concurrent connections](https://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser)
  237. (this limit is not counting native WebSocket connections).
  238. * Although SockJS is trying to escape any strange Unicode characters
  239. (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))
  240. it's advisable to use only valid characters. Using invalid
  241. characters is a bit slower, and may not work with SockJS servers
  242. that have proper Unicode support.
  243. * Having a global function called `onmessage` or such is probably a
  244. bad idea, as it could be called by the built-in `postMessage` API.
  245. * From SockJS' point of view there is nothing special about
  246. SSL/HTTPS. Connecting between unencrypted and encrypted sites
  247. should work just fine.
  248. * Although SockJS does its best to support both prefix and cookie based
  249. sticky sessions, the latter may not work well cross-domain with
  250. browsers that don't accept third-party cookies by default (Safari).
  251. In order to get around this make sure you're connecting to SockJS
  252. from the same parent domain as the main site. For example
  253. 'sockjs.a.com' is able to set cookies if you're connecting from
  254. 'www.a.com' or 'a.com'.
  255. * Trying to connect from secure "https://" to insecure "http://" is
  256. not a good idea. The other way around should be fine.
  257. * Long polling is known to cause problems on Heroku, but a
  258. [workaround for SockJS is available](https://github.com/sockjs/sockjs-node/issues/57#issuecomment-5242187).
  259. * SockJS [websocket transport is more stable over SSL](https://github.com/sockjs/sockjs-client/issues/94). If
  260. you're a serious SockJS user then consider using SSL
  261. ([more info](https://www.ietf.org/mail-archive/web/hybi/current/msg01605.html)).