mirror of
				https://github.com/1disk/edp445.git
				synced 2024-08-14 22:47:02 +00:00 
			
		
		
		
	Changed alot of things.
This commit is contained in:
		
							parent
							
								
									a5a0523e5a
								
							
						
					
					
						commit
						3513d5390c
					
				
					 2016 changed files with 336930 additions and 9 deletions
				
			
		
							
								
								
									
										495
									
								
								node_modules/ws/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										495
									
								
								node_modules/ws/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,495 @@ | |||
| # ws: a Node.js WebSocket library | ||||
| 
 | ||||
| [](https://www.npmjs.com/package/ws) | ||||
| [](https://github.com/websockets/ws/actions?query=workflow%3ACI+branch%3Amaster) | ||||
| [](https://coveralls.io/github/websockets/ws) | ||||
| 
 | ||||
| ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and | ||||
| server implementation. | ||||
| 
 | ||||
| Passes the quite extensive Autobahn test suite: [server][server-report], | ||||
| [client][client-report]. | ||||
| 
 | ||||
| **Note**: This module does not work in the browser. The client in the docs is a | ||||
| reference to a back end with the role of a client in the WebSocket | ||||
| communication. Browser clients must use the native | ||||
| [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) | ||||
| object. To make the same code work seamlessly on Node.js and the browser, you | ||||
| can use one of the many wrappers available on npm, like | ||||
| [isomorphic-ws](https://github.com/heineiuo/isomorphic-ws). | ||||
| 
 | ||||
| ## Table of Contents | ||||
| 
 | ||||
| - [Protocol support](#protocol-support) | ||||
| - [Installing](#installing) | ||||
|   - [Opt-in for performance](#opt-in-for-performance) | ||||
| - [API docs](#api-docs) | ||||
| - [WebSocket compression](#websocket-compression) | ||||
| - [Usage examples](#usage-examples) | ||||
|   - [Sending and receiving text data](#sending-and-receiving-text-data) | ||||
|   - [Sending binary data](#sending-binary-data) | ||||
|   - [Simple server](#simple-server) | ||||
|   - [External HTTP/S server](#external-https-server) | ||||
|   - [Multiple servers sharing a single HTTP/S server](#multiple-servers-sharing-a-single-https-server) | ||||
|   - [Client authentication](#client-authentication) | ||||
|   - [Server broadcast](#server-broadcast) | ||||
|   - [echo.websocket.org demo](#echowebsocketorg-demo) | ||||
|   - [Use the Node.js streams API](#use-the-nodejs-streams-api) | ||||
|   - [Other examples](#other-examples) | ||||
| - [FAQ](#faq) | ||||
|   - [How to get the IP address of the client?](#how-to-get-the-ip-address-of-the-client) | ||||
|   - [How to detect and close broken connections?](#how-to-detect-and-close-broken-connections) | ||||
|   - [How to connect via a proxy?](#how-to-connect-via-a-proxy) | ||||
| - [Changelog](#changelog) | ||||
| - [License](#license) | ||||
| 
 | ||||
| ## Protocol support | ||||
| 
 | ||||
| - **HyBi drafts 07-12** (Use the option `protocolVersion: 8`) | ||||
| - **HyBi drafts 13-17** (Current default, alternatively option | ||||
|   `protocolVersion: 13`) | ||||
| 
 | ||||
| ## Installing | ||||
| 
 | ||||
| ``` | ||||
| npm install ws | ||||
| ``` | ||||
| 
 | ||||
| ### Opt-in for performance | ||||
| 
 | ||||
| There are 2 optional modules that can be installed along side with the ws | ||||
| module. These modules are binary addons which improve certain operations. | ||||
| Prebuilt binaries are available for the most popular platforms so you don't | ||||
| necessarily need to have a C++ compiler installed on your machine. | ||||
| 
 | ||||
| - `npm install --save-optional bufferutil`: Allows to efficiently perform | ||||
|   operations such as masking and unmasking the data payload of the WebSocket | ||||
|   frames. | ||||
| - `npm install --save-optional utf-8-validate`: Allows to efficiently check if a | ||||
|   message contains valid UTF-8. | ||||
| 
 | ||||
| ## API docs | ||||
| 
 | ||||
| See [`/doc/ws.md`](./doc/ws.md) for Node.js-like documentation of ws classes and | ||||
| utility functions. | ||||
| 
 | ||||
| ## WebSocket compression | ||||
| 
 | ||||
| ws supports the [permessage-deflate extension][permessage-deflate] which enables | ||||
| the client and server to negotiate a compression algorithm and its parameters, | ||||
| and then selectively apply it to the data payloads of each WebSocket message. | ||||
| 
 | ||||
| The extension is disabled by default on the server and enabled by default on the | ||||
| client. It adds a significant overhead in terms of performance and memory | ||||
| consumption so we suggest to enable it only if it is really needed. | ||||
| 
 | ||||
| Note that Node.js has a variety of issues with high-performance compression, | ||||
| where increased concurrency, especially on Linux, can lead to [catastrophic | ||||
| memory fragmentation][node-zlib-bug] and slow performance. If you intend to use | ||||
| permessage-deflate in production, it is worthwhile to set up a test | ||||
| representative of your workload and ensure Node.js/zlib will handle it with | ||||
| acceptable performance and memory usage. | ||||
| 
 | ||||
| Tuning of permessage-deflate can be done via the options defined below. You can | ||||
| also use `zlibDeflateOptions` and `zlibInflateOptions`, which is passed directly | ||||
| into the creation of [raw deflate/inflate streams][node-zlib-deflaterawdocs]. | ||||
| 
 | ||||
| See [the docs][ws-server-options] for more options. | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const wss = new WebSocket.Server({ | ||||
|   port: 8080, | ||||
|   perMessageDeflate: { | ||||
|     zlibDeflateOptions: { | ||||
|       // See zlib defaults. | ||||
|       chunkSize: 1024, | ||||
|       memLevel: 7, | ||||
|       level: 3 | ||||
|     }, | ||||
|     zlibInflateOptions: { | ||||
|       chunkSize: 10 * 1024 | ||||
|     }, | ||||
|     // Other options settable: | ||||
|     clientNoContextTakeover: true, // Defaults to negotiated value. | ||||
|     serverNoContextTakeover: true, // Defaults to negotiated value. | ||||
|     serverMaxWindowBits: 10, // Defaults to negotiated value. | ||||
|     // Below options specified as default values. | ||||
|     concurrencyLimit: 10, // Limits zlib concurrency for perf. | ||||
|     threshold: 1024 // Size (in bytes) below which messages | ||||
|     // should not be compressed. | ||||
|   } | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| The client will only use the extension if it is supported and enabled on the | ||||
| server. To always disable the extension on the client set the | ||||
| `perMessageDeflate` option to `false`. | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const ws = new WebSocket('ws://www.host.com/path', { | ||||
|   perMessageDeflate: false | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ## Usage examples | ||||
| 
 | ||||
| ### Sending and receiving text data | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const ws = new WebSocket('ws://www.host.com/path'); | ||||
| 
 | ||||
| ws.on('open', function open() { | ||||
|   ws.send('something'); | ||||
| }); | ||||
| 
 | ||||
| ws.on('message', function incoming(data) { | ||||
|   console.log(data); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ### Sending binary data | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const ws = new WebSocket('ws://www.host.com/path'); | ||||
| 
 | ||||
| ws.on('open', function open() { | ||||
|   const array = new Float32Array(5); | ||||
| 
 | ||||
|   for (var i = 0; i < array.length; ++i) { | ||||
|     array[i] = i / 2; | ||||
|   } | ||||
| 
 | ||||
|   ws.send(array); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ### Simple server | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const wss = new WebSocket.Server({ port: 8080 }); | ||||
| 
 | ||||
| wss.on('connection', function connection(ws) { | ||||
|   ws.on('message', function incoming(message) { | ||||
|     console.log('received: %s', message); | ||||
|   }); | ||||
| 
 | ||||
|   ws.send('something'); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ### External HTTP/S server | ||||
| 
 | ||||
| ```js | ||||
| const fs = require('fs'); | ||||
| const https = require('https'); | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const server = https.createServer({ | ||||
|   cert: fs.readFileSync('/path/to/cert.pem'), | ||||
|   key: fs.readFileSync('/path/to/key.pem') | ||||
| }); | ||||
| const wss = new WebSocket.Server({ server }); | ||||
| 
 | ||||
| wss.on('connection', function connection(ws) { | ||||
|   ws.on('message', function incoming(message) { | ||||
|     console.log('received: %s', message); | ||||
|   }); | ||||
| 
 | ||||
|   ws.send('something'); | ||||
| }); | ||||
| 
 | ||||
| server.listen(8080); | ||||
| ``` | ||||
| 
 | ||||
| ### Multiple servers sharing a single HTTP/S server | ||||
| 
 | ||||
| ```js | ||||
| const http = require('http'); | ||||
| const WebSocket = require('ws'); | ||||
| const url = require('url'); | ||||
| 
 | ||||
| const server = http.createServer(); | ||||
| const wss1 = new WebSocket.Server({ noServer: true }); | ||||
| const wss2 = new WebSocket.Server({ noServer: true }); | ||||
| 
 | ||||
| wss1.on('connection', function connection(ws) { | ||||
|   // ... | ||||
| }); | ||||
| 
 | ||||
| wss2.on('connection', function connection(ws) { | ||||
|   // ... | ||||
| }); | ||||
| 
 | ||||
| server.on('upgrade', function upgrade(request, socket, head) { | ||||
|   const pathname = url.parse(request.url).pathname; | ||||
| 
 | ||||
|   if (pathname === '/foo') { | ||||
|     wss1.handleUpgrade(request, socket, head, function done(ws) { | ||||
|       wss1.emit('connection', ws, request); | ||||
|     }); | ||||
|   } else if (pathname === '/bar') { | ||||
|     wss2.handleUpgrade(request, socket, head, function done(ws) { | ||||
|       wss2.emit('connection', ws, request); | ||||
|     }); | ||||
|   } else { | ||||
|     socket.destroy(); | ||||
|   } | ||||
| }); | ||||
| 
 | ||||
| server.listen(8080); | ||||
| ``` | ||||
| 
 | ||||
| ### Client authentication | ||||
| 
 | ||||
| ```js | ||||
| const http = require('http'); | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const server = http.createServer(); | ||||
| const wss = new WebSocket.Server({ noServer: true }); | ||||
| 
 | ||||
| wss.on('connection', function connection(ws, request, client) { | ||||
|   ws.on('message', function message(msg) { | ||||
|     console.log(`Received message ${msg} from user ${client}`); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| server.on('upgrade', function upgrade(request, socket, head) { | ||||
|   // This function is not defined on purpose. Implement it with your own logic. | ||||
|   authenticate(request, (err, client) => { | ||||
|     if (err || !client) { | ||||
|       socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n'); | ||||
|       socket.destroy(); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     wss.handleUpgrade(request, socket, head, function done(ws) { | ||||
|       wss.emit('connection', ws, request, client); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| server.listen(8080); | ||||
| ``` | ||||
| 
 | ||||
| Also see the provided [example][session-parse-example] using `express-session`. | ||||
| 
 | ||||
| ### Server broadcast | ||||
| 
 | ||||
| A client WebSocket broadcasting to all connected WebSocket clients, including | ||||
| itself. | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const wss = new WebSocket.Server({ port: 8080 }); | ||||
| 
 | ||||
| wss.on('connection', function connection(ws) { | ||||
|   ws.on('message', function incoming(data) { | ||||
|     wss.clients.forEach(function each(client) { | ||||
|       if (client.readyState === WebSocket.OPEN) { | ||||
|         client.send(data); | ||||
|       } | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| A client WebSocket broadcasting to every other connected WebSocket clients, | ||||
| excluding itself. | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const wss = new WebSocket.Server({ port: 8080 }); | ||||
| 
 | ||||
| wss.on('connection', function connection(ws) { | ||||
|   ws.on('message', function incoming(data) { | ||||
|     wss.clients.forEach(function each(client) { | ||||
|       if (client !== ws && client.readyState === WebSocket.OPEN) { | ||||
|         client.send(data); | ||||
|       } | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ### echo.websocket.org demo | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const ws = new WebSocket('wss://echo.websocket.org/', { | ||||
|   origin: 'https://websocket.org' | ||||
| }); | ||||
| 
 | ||||
| ws.on('open', function open() { | ||||
|   console.log('connected'); | ||||
|   ws.send(Date.now()); | ||||
| }); | ||||
| 
 | ||||
| ws.on('close', function close() { | ||||
|   console.log('disconnected'); | ||||
| }); | ||||
| 
 | ||||
| ws.on('message', function incoming(data) { | ||||
|   console.log(`Roundtrip time: ${Date.now() - data} ms`); | ||||
| 
 | ||||
|   setTimeout(function timeout() { | ||||
|     ws.send(Date.now()); | ||||
|   }, 500); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ### Use the Node.js streams API | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const ws = new WebSocket('wss://echo.websocket.org/', { | ||||
|   origin: 'https://websocket.org' | ||||
| }); | ||||
| 
 | ||||
| const duplex = WebSocket.createWebSocketStream(ws, { encoding: 'utf8' }); | ||||
| 
 | ||||
| duplex.pipe(process.stdout); | ||||
| process.stdin.pipe(duplex); | ||||
| ``` | ||||
| 
 | ||||
| ### Other examples | ||||
| 
 | ||||
| For a full example with a browser client communicating with a ws server, see the | ||||
| examples folder. | ||||
| 
 | ||||
| Otherwise, see the test cases. | ||||
| 
 | ||||
| ## FAQ | ||||
| 
 | ||||
| ### How to get the IP address of the client? | ||||
| 
 | ||||
| The remote IP address can be obtained from the raw socket. | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| const wss = new WebSocket.Server({ port: 8080 }); | ||||
| 
 | ||||
| wss.on('connection', function connection(ws, req) { | ||||
|   const ip = req.socket.remoteAddress; | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| When the server runs behind a proxy like NGINX, the de-facto standard is to use | ||||
| the `X-Forwarded-For` header. | ||||
| 
 | ||||
| ```js | ||||
| wss.on('connection', function connection(ws, req) { | ||||
|   const ip = req.headers['x-forwarded-for'].split(',')[0].trim(); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ### How to detect and close broken connections? | ||||
| 
 | ||||
| Sometimes the link between the server and the client can be interrupted in a way | ||||
| that keeps both the server and the client unaware of the broken state of the | ||||
| connection (e.g. when pulling the cord). | ||||
| 
 | ||||
| In these cases ping messages can be used as a means to verify that the remote | ||||
| endpoint is still responsive. | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| function noop() {} | ||||
| 
 | ||||
| function heartbeat() { | ||||
|   this.isAlive = true; | ||||
| } | ||||
| 
 | ||||
| const wss = new WebSocket.Server({ port: 8080 }); | ||||
| 
 | ||||
| wss.on('connection', function connection(ws) { | ||||
|   ws.isAlive = true; | ||||
|   ws.on('pong', heartbeat); | ||||
| }); | ||||
| 
 | ||||
| const interval = setInterval(function ping() { | ||||
|   wss.clients.forEach(function each(ws) { | ||||
|     if (ws.isAlive === false) return ws.terminate(); | ||||
| 
 | ||||
|     ws.isAlive = false; | ||||
|     ws.ping(noop); | ||||
|   }); | ||||
| }, 30000); | ||||
| 
 | ||||
| wss.on('close', function close() { | ||||
|   clearInterval(interval); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| Pong messages are automatically sent in response to ping messages as required by | ||||
| the spec. | ||||
| 
 | ||||
| Just like the server example above your clients might as well lose connection | ||||
| without knowing it. You might want to add a ping listener on your clients to | ||||
| prevent that. A simple implementation would be: | ||||
| 
 | ||||
| ```js | ||||
| const WebSocket = require('ws'); | ||||
| 
 | ||||
| function heartbeat() { | ||||
|   clearTimeout(this.pingTimeout); | ||||
| 
 | ||||
|   // Use `WebSocket#terminate()`, which immediately destroys the connection, | ||||
|   // instead of `WebSocket#close()`, which waits for the close timer. | ||||
|   // Delay should be equal to the interval at which your server | ||||
|   // sends out pings plus a conservative assumption of the latency. | ||||
|   this.pingTimeout = setTimeout(() => { | ||||
|     this.terminate(); | ||||
|   }, 30000 + 1000); | ||||
| } | ||||
| 
 | ||||
| const client = new WebSocket('wss://echo.websocket.org/'); | ||||
| 
 | ||||
| client.on('open', heartbeat); | ||||
| client.on('ping', heartbeat); | ||||
| client.on('close', function clear() { | ||||
|   clearTimeout(this.pingTimeout); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ### How to connect via a proxy? | ||||
| 
 | ||||
| Use a custom `http.Agent` implementation like [https-proxy-agent][] or | ||||
| [socks-proxy-agent][]. | ||||
| 
 | ||||
| ## Changelog | ||||
| 
 | ||||
| We're using the GitHub [releases][changelog] for changelog entries. | ||||
| 
 | ||||
| ## License | ||||
| 
 | ||||
| [MIT](LICENSE) | ||||
| 
 | ||||
| [changelog]: https://github.com/websockets/ws/releases | ||||
| [client-report]: http://websockets.github.io/ws/autobahn/clients/ | ||||
| [https-proxy-agent]: https://github.com/TooTallNate/node-https-proxy-agent | ||||
| [node-zlib-bug]: https://github.com/nodejs/node/issues/8871 | ||||
| [node-zlib-deflaterawdocs]: | ||||
|   https://nodejs.org/api/zlib.html#zlib_zlib_createdeflateraw_options | ||||
| [permessage-deflate]: https://tools.ietf.org/html/rfc7692 | ||||
| [server-report]: http://websockets.github.io/ws/autobahn/servers/ | ||||
| [session-parse-example]: ./examples/express-session-parse | ||||
| [socks-proxy-agent]: https://github.com/TooTallNate/node-socks-proxy-agent | ||||
| [ws-server-options]: | ||||
|   https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue