source: trip-planner-front/node_modules/engine.io/README.md@ 6c1585f

Last change on this file since 6c1585f was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 20.3 KB
Line 
1
2# Engine.IO: the realtime engine
3
4[![Build Status](https://github.com/socketio/engine.io/workflows/CI/badge.svg?branch=master))](https://github.com/socketio/engine.io/actions)
5[![NPM version](https://badge.fury.io/js/engine.io.svg)](http://badge.fury.io/js/engine.io)
6
7`Engine.IO` is the implementation of transport-based
8cross-browser/cross-device bi-directional communication layer for
9[Socket.IO](http://github.com/socketio/socket.io).
10
11## How to use
12
13### Server
14
15#### (A) Listening on a port
16
17```js
18const engine = require('engine.io');
19const server = engine.listen(80);
20
21server.on('connection', socket => {
22 socket.send('utf 8 string');
23 socket.send(Buffer.from([0, 1, 2, 3, 4, 5])); // binary data
24});
25```
26
27#### (B) Intercepting requests for a http.Server
28
29```js
30const engine = require('engine.io');
31const http = require('http').createServer().listen(3000);
32const server = engine.attach(http);
33
34server.on('connection', socket => {
35 socket.on('message', data => { });
36 socket.on('close', () => { });
37});
38```
39
40#### (C) Passing in requests
41
42```js
43const engine = require('engine.io');
44const server = new engine.Server();
45
46server.on('connection', socket => {
47 socket.send('hi');
48});
49
50// …
51httpServer.on('upgrade', (req, socket, head) => {
52 server.handleUpgrade(req, socket, head);
53});
54
55httpServer.on('request', (req, res) => {
56 server.handleRequest(req, res);
57});
58```
59
60### Client
61
62```html
63<script src="/path/to/engine.io.js"></script>
64<script>
65 const socket = new eio.Socket('ws://localhost/');
66 socket.on('open', () => {
67 socket.on('message', data => {});
68 socket.on('close', () => {});
69 });
70</script>
71```
72
73For more information on the client refer to the
74[engine-client](http://github.com/socketio/engine.io-client) repository.
75
76## What features does it have?
77
78- **Maximum reliability**. Connections are established even in the presence of:
79 - proxies and load balancers.
80 - personal firewall and antivirus software.
81 - for more information refer to **Goals** and **Architecture** sections
82- **Minimal client size** aided by:
83 - lazy loading of flash transports.
84 - lack of redundant transports.
85- **Scalable**
86 - load balancer friendly
87- **Future proof**
88- **100% Node.JS core style**
89 - No API sugar (left for higher level projects)
90 - Written in readable vanilla JavaScript
91
92## API
93
94### Server
95
96<hr><br>
97
98#### Top-level
99
100These are exposed by `require('engine.io')`:
101
102##### Events
103
104- `flush`
105 - Called when a socket buffer is being flushed.
106 - **Arguments**
107 - `Socket`: socket being flushed
108 - `Array`: write buffer
109- `drain`
110 - Called when a socket buffer is drained
111 - **Arguments**
112 - `Socket`: socket being flushed
113
114##### Properties
115
116- `protocol` _(Number)_: protocol revision number
117- `Server`: Server class constructor
118- `Socket`: Socket class constructor
119- `Transport` _(Function)_: transport constructor
120- `transports` _(Object)_: map of available transports
121
122##### Methods
123
124- `()`
125 - Returns a new `Server` instance. If the first argument is an `http.Server` then the
126 new `Server` instance will be attached to it. Otherwise, the arguments are passed
127 directly to the `Server` constructor.
128 - **Parameters**
129 - `http.Server`: optional, server to attach to.
130 - `Object`: optional, options object (see `Server#constructor` api docs below)
131
132 The following are identical ways to instantiate a server and then attach it.
133
134```js
135const httpServer; // previously created with `http.createServer();` from node.js api.
136
137// create a server first, and then attach
138const eioServer = require('engine.io').Server();
139eioServer.attach(httpServer);
140
141// or call the module as a function to get `Server`
142const eioServer = require('engine.io')();
143eioServer.attach(httpServer);
144
145// immediately attach
146const eioServer = require('engine.io')(httpServer);
147
148// with custom options
149const eioServer = require('engine.io')(httpServer, {
150 maxHttpBufferSize: 1e3
151});
152```
153
154- `listen`
155 - Creates an `http.Server` which listens on the given port and attaches WS
156 to it. It returns `501 Not Implemented` for regular http requests.
157 - **Parameters**
158 - `Number`: port to listen on.
159 - `Object`: optional, options object
160 - `Function`: callback for `listen`.
161 - **Options**
162 - All options from `Server.attach` method, documented below.
163 - **Additionally** See Server `constructor` below for options you can pass for creating the new Server
164 - **Returns** `Server`
165
166```js
167const engine = require('engine.io');
168const server = engine.listen(3000, {
169 pingTimeout: 2000,
170 pingInterval: 10000
171});
172
173server.on('connection', /* ... */);
174```
175
176- `attach`
177 - Captures `upgrade` requests for a `http.Server`. In other words, makes
178 a regular http.Server WebSocket-compatible.
179 - **Parameters**
180 - `http.Server`: server to attach to.
181 - `Object`: optional, options object
182 - **Options**
183 - All options from `Server.attach` method, documented below.
184 - **Additionally** See Server `constructor` below for options you can pass for creating the new Server
185 - **Returns** `Server` a new Server instance.
186
187```js
188const engine = require('engine.io');
189const httpServer = require('http').createServer().listen(3000);
190const server = engine.attach(httpServer, {
191 wsEngine: 'uws' // requires having uws as dependency
192});
193
194server.on('connection', /* ... */);
195```
196
197#### Server
198
199The main server/manager. _Inherits from EventEmitter_.
200
201##### Events
202
203- `connection`
204 - Fired when a new connection is established.
205 - **Arguments**
206 - `Socket`: a Socket object
207
208##### Properties
209
210**Important**: if you plan to use Engine.IO in a scalable way, please
211keep in mind the properties below will only reflect the clients connected
212to a single process.
213
214- `clients` _(Object)_: hash of connected clients by id.
215- `clientsCount` _(Number)_: number of connected clients.
216
217##### Methods
218
219- **constructor**
220 - Initializes the server
221 - **Parameters**
222 - `Object`: optional, options object
223 - **Options**
224 - `pingTimeout` (`Number`): how many ms without a pong packet to
225 consider the connection closed (`5000`)
226 - `pingInterval` (`Number`): how many ms before sending a new ping
227 packet (`25000`)
228 - `upgradeTimeout` (`Number`): how many ms before an uncompleted transport upgrade is cancelled (`10000`)
229 - `maxHttpBufferSize` (`Number`): how many bytes or characters a message
230 can be, before closing the session (to avoid DoS). Default
231 value is `1E6`.
232 - `allowRequest` (`Function`): A function that receives a given handshake
233 or upgrade request as its first parameter, and can decide whether to
234 continue or not. The second argument is a function that needs to be
235 called with the decided information: `fn(err, success)`, where
236 `success` is a boolean value where false means that the request is
237 rejected, and err is an error code.
238 - `transports` (`<Array> String`): transports to allow connections
239 to (`['polling', 'websocket']`)
240 - `allowUpgrades` (`Boolean`): whether to allow transport upgrades
241 (`true`)
242 - `perMessageDeflate` (`Object|Boolean`): parameters of the WebSocket permessage-deflate extension
243 (see [ws module](https://github.com/einaros/ws) api docs). Set to `true` to enable. (defaults to `false`)
244 - `threshold` (`Number`): data is compressed only if the byte size is above this value (`1024`)
245 - `httpCompression` (`Object|Boolean`): parameters of the http compression for the polling transports
246 (see [zlib](http://nodejs.org/api/zlib.html#zlib_options) api docs). Set to `false` to disable. (`true`)
247 - `threshold` (`Number`): data is compressed only if the byte size is above this value (`1024`)
248 - `cookie` (`Object|Boolean`): configuration of the cookie that
249 contains the client sid to send as part of handshake response
250 headers. This cookie might be used for sticky-session. Defaults to not sending any cookie (`false`).
251 See [here](https://github.com/jshttp/cookie#options-1) for all supported options.
252 - `wsEngine` (`String`): what WebSocket server implementation to use. Specified module must conform to the `ws` interface (see [ws module api docs](https://github.com/websockets/ws/blob/master/doc/ws.md)). Default value is `ws`. An alternative c++ addon is also available by installing `uws` module.
253 - `cors` (`Object`): the options that will be forwarded to the cors module. See [there](https://github.com/expressjs/cors#configuration-options) for all available options. Defaults to no CORS allowed.
254 - `initialPacket` (`Object`): an optional packet which will be concatenated to the handshake packet emitted by Engine.IO.
255 - `allowEIO3` (`Boolean`): whether to support v3 Engine.IO clients (defaults to `false`)
256- `close`
257 - Closes all clients
258 - **Returns** `Server` for chaining
259- `handleRequest`
260 - Called internally when a `Engine` request is intercepted.
261 - **Parameters**
262 - `http.IncomingMessage`: a node request object
263 - `http.ServerResponse`: a node response object
264 - **Returns** `Server` for chaining
265- `handleUpgrade`
266 - Called internally when a `Engine` ws upgrade is intercepted.
267 - **Parameters** (same as `upgrade` event)
268 - `http.IncomingMessage`: a node request object
269 - `net.Stream`: TCP socket for the request
270 - `Buffer`: legacy tail bytes
271 - **Returns** `Server` for chaining
272- `attach`
273 - Attach this Server instance to an `http.Server`
274 - Captures `upgrade` requests for a `http.Server`. In other words, makes
275 a regular http.Server WebSocket-compatible.
276 - **Parameters**
277 - `http.Server`: server to attach to.
278 - `Object`: optional, options object
279 - **Options**
280 - `path` (`String`): name of the path to capture (`/engine.io`).
281 - `destroyUpgrade` (`Boolean`): destroy unhandled upgrade requests (`true`)
282 - `destroyUpgradeTimeout` (`Number`): milliseconds after which unhandled requests are ended (`1000`)
283- `generateId`
284 - Generate a socket id.
285 - Overwrite this method to generate your custom socket id.
286 - **Parameters**
287 - `http.IncomingMessage`: a node request object
288 - **Returns** A socket id for connected client.
289
290<hr><br>
291
292#### Socket
293
294A representation of a client. _Inherits from EventEmitter_.
295
296##### Events
297
298- `close`
299 - Fired when the client is disconnected.
300 - **Arguments**
301 - `String`: reason for closing
302 - `Object`: description object (optional)
303- `message`
304 - Fired when the client sends a message.
305 - **Arguments**
306 - `String` or `Buffer`: Unicode string or Buffer with binary contents
307- `error`
308 - Fired when an error occurs.
309 - **Arguments**
310 - `Error`: error object
311- `flush`
312 - Called when the write buffer is being flushed.
313 - **Arguments**
314 - `Array`: write buffer
315- `drain`
316 - Called when the write buffer is drained
317- `packet`
318 - Called when a socket received a packet (`message`, `ping`)
319 - **Arguments**
320 - `type`: packet type
321 - `data`: packet data (if type is message)
322- `packetCreate`
323 - Called before a socket sends a packet (`message`, `ping`)
324 - **Arguments**
325 - `type`: packet type
326 - `data`: packet data (if type is message)
327
328##### Properties
329
330- `id` _(String)_: unique identifier
331- `server` _(Server)_: engine parent reference
332- `request` _(http.IncomingMessage)_: request that originated the Socket
333- `upgraded` _(Boolean)_: whether the transport has been upgraded
334- `readyState` _(String)_: opening|open|closing|closed
335- `transport` _(Transport)_: transport reference
336
337##### Methods
338
339- `send`:
340 - Sends a message, performing `message = toString(arguments[0])` unless
341 sending binary data, which is sent as is.
342 - **Parameters**
343 - `String` | `Buffer` | `ArrayBuffer` | `ArrayBufferView`: a string or any object implementing `toString()`, with outgoing data, or a Buffer or ArrayBuffer with binary data. Also any ArrayBufferView can be sent as is.
344 - `Object`: optional, options object
345 - `Function`: optional, a callback executed when the message gets flushed out by the transport
346 - **Options**
347 - `compress` (`Boolean`): whether to compress sending data. This option might be ignored and forced to be `true` when using polling. (`true`)
348 - **Returns** `Socket` for chaining
349- `close`
350 - Disconnects the client
351 - **Returns** `Socket` for chaining
352
353### Client
354
355<hr><br>
356
357Exposed in the `eio` global namespace (in the browser), or by
358`require('engine.io-client')` (in Node.JS).
359
360For the client API refer to the
361[engine-client](http://github.com/learnboost/engine.io-client) repository.
362
363## Debug / logging
364
365Engine.IO is powered by [debug](http://github.com/visionmedia/debug).
366In order to see all the debug output, run your app with the environment variable
367`DEBUG` including the desired scope.
368
369To see the output from all of Engine.IO's debugging scopes you can use:
370
371```
372DEBUG=engine* node myapp
373```
374
375## Transports
376
377- `polling`: XHR / JSONP polling transport.
378- `websocket`: WebSocket transport.
379
380## Plugins
381
382- [engine.io-conflation](https://github.com/EugenDueck/engine.io-conflation): Makes **conflation and aggregation** of messages straightforward.
383
384## Support
385
386The support channels for `engine.io` are the same as `socket.io`:
387 - irc.freenode.net **#socket.io**
388 - [Google Groups](http://groups.google.com/group/socket_io)
389 - [Website](http://socket.io)
390
391## Development
392
393To contribute patches, run tests or benchmarks, make sure to clone the
394repository:
395
396```
397git clone git://github.com/LearnBoost/engine.io.git
398```
399
400Then:
401
402```
403cd engine.io
404npm install
405```
406
407## Tests
408
409Tests run with `npm test`. It runs the server tests that are aided by
410the usage of `engine.io-client`.
411
412Make sure `npm install` is run first.
413
414## Goals
415
416The main goal of `Engine` is ensuring the most reliable realtime communication.
417Unlike the previous Socket.IO core, it always establishes a long-polling
418connection first, then tries to upgrade to better transports that are "tested" on
419the side.
420
421During the lifetime of the Socket.IO projects, we've found countless drawbacks
422to relying on `HTML5 WebSocket` or `Flash Socket` as the first connection
423mechanisms.
424
425Both are clearly the _right way_ of establishing a bidirectional communication,
426with HTML5 WebSocket being the way of the future. However, to answer most business
427needs, alternative traditional HTTP 1.1 mechanisms are just as good as delivering
428the same solution.
429
430WebSocket based connections have two fundamental benefits:
431
4321. **Better server performance**
433 - _A: Load balancers_<br>
434 Load balancing a long polling connection poses a serious architectural nightmare
435 since requests can come from any number of open sockets by the user agent, but
436 they all need to be routed to the process and computer that owns the `Engine`
437 connection. This negatively impacts RAM and CPU usage.
438 - _B: Network traffic_<br>
439 WebSocket is designed around the premise that each message frame has to be
440 surrounded by the least amount of data. In HTTP 1.1 transports, each message
441 frame is surrounded by HTTP headers and chunked encoding frames. If you try to
442 send the message _"Hello world"_ with xhr-polling, the message ultimately
443 becomes larger than if you were to send it with WebSocket.
444 - _C: Lightweight parser_<br>
445 As an effect of **B**, the server has to do a lot more work to parse the network
446 data and figure out the message when traditional HTTP requests are used
447 (as in long polling). This means that another advantage of WebSocket is
448 less server CPU usage.
449
4502. **Better user experience**
451
452 Due to the reasons stated in point **1**, the most important effect of being able
453 to establish a WebSocket connection is raw data transfer speed, which translates
454 in _some_ cases in better user experience.
455
456 Applications with heavy realtime interaction (such as games) will benefit greatly,
457 whereas applications like realtime chat (Gmail/Facebook), newsfeeds (Facebook) or
458 timelines (Twitter) will have negligible user experience improvements.
459
460Having said this, attempting to establish a WebSocket connection directly so far has
461proven problematic:
462
4631. **Proxies**<br>
464 Many corporate proxies block WebSocket traffic.
465
4662. **Personal firewall and antivirus software**<br>
467 As a result of our research, we've found that at least 3 personal security
468 applications block WebSocket traffic.
469
4703. **Cloud application platforms**<br>
471 Platforms like Heroku or No.de have had trouble keeping up with the fast-paced
472 nature of the evolution of the WebSocket protocol. Applications therefore end up
473 inevitably using long polling, but the seamless installation experience of
474 Socket.IO we strive for (_"require() it and it just works"_) disappears.
475
476Some of these problems have solutions. In the case of proxies and personal programs,
477however, the solutions many times involve upgrading software. Experience has shown
478that relying on client software upgrades to deliver a business solution is
479fruitless: the very existence of this project has to do with a fragmented panorama
480of user agent distribution, with clients connecting with latest versions of the most
481modern user agents (Chrome, Firefox and Safari), but others with versions as low as
482IE 5.5.
483
484From the user perspective, an unsuccessful WebSocket connection can translate in
485up to at least 10 seconds of waiting for the realtime application to begin
486exchanging data. This **perceptively** hurts user experience.
487
488To summarize, **Engine** focuses on reliability and user experience first, marginal
489potential UX improvements and increased server performance second. `Engine` is the
490result of all the lessons learned with WebSocket in the wild.
491
492## Architecture
493
494The main premise of `Engine`, and the core of its existence, is the ability to
495swap transports on the fly. A connection starts as xhr-polling, but it can
496switch to WebSocket.
497
498The central problem this poses is: how do we switch transports without losing
499messages?
500
501`Engine` only switches from polling to another transport in between polling
502cycles. Since the server closes the connection after a certain timeout when
503there's no activity, and the polling transport implementation buffers messages
504in between connections, this ensures no message loss and optimal performance.
505
506Another benefit of this design is that we workaround almost all the limitations
507of **Flash Socket**, such as slow connection times, increased file size (we can
508safely lazy load it without hurting user experience), etc.
509
510## FAQ
511
512### Can I use engine without Socket.IO ?
513
514Absolutely. Although the recommended framework for building realtime applications
515is Socket.IO, since it provides fundamental features for real-world applications
516such as multiplexing, reconnection support, etc.
517
518`Engine` is to Socket.IO what Connect is to Express. An essential piece for building
519realtime frameworks, but something you _probably_ won't be using for building
520actual applications.
521
522### Does the server serve the client?
523
524No. The main reason is that `Engine` is meant to be bundled with frameworks.
525Socket.IO includes `Engine`, therefore serving two clients is not necessary. If
526you use Socket.IO, including
527
528```html
529<script src="/socket.io/socket.io.js">
530```
531
532has you covered.
533
534### Can I implement `Engine` in other languages?
535
536Absolutely. The [engine.io-protocol](https://github.com/socketio/engine.io-protocol)
537repository contains the most up-to-date description of the specification
538at all times.
539
540## License
541
542(The MIT License)
543
544Copyright (c) 2014 Guillermo Rauch &lt;guillermo@learnboost.com&gt;
545
546Permission is hereby granted, free of charge, to any person obtaining
547a copy of this software and associated documentation files (the
548'Software'), to deal in the Software without restriction, including
549without limitation the rights to use, copy, modify, merge, publish,
550distribute, sublicense, and/or sell copies of the Software, and to
551permit persons to whom the Software is furnished to do so, subject to
552the following conditions:
553
554The above copyright notice and this permission notice shall be
555included in all copies or substantial portions of the Software.
556
557THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
558EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
559MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
560IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
561CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
562TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
563SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Note: See TracBrowser for help on using the repository browser.