Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Pédagogies Multimodales
PhonoDrop
Commits
6d4909ed
Commit
6d4909ed
authored
Jan 06, 2022
by
Sylvain Coulange
🌼
Browse files
test npm ws
parent
7fc26a3b
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
node_modules/ws/LICENSE
0 → 100644
View file @
6d4909ed
Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
node_modules/ws/README.md
0 → 100644
View file @
6d4909ed
# 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
import
WebSocket
,
{
WebSocketServer
}
from
'
ws
'
;
const
wss
=
new
WebSocketServer
({
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 if context takeover is disabled.
}
});
```
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
import
WebSocket
from
'
ws
'
;
const
ws
=
new
WebSocket
(
'
ws://www.host.com/path
'
,
{
perMessageDeflate
:
false
});
```
## Usage examples
### Sending and receiving text data
```
js
import
WebSocket
from
'
ws
'
;
const
ws
=
new
WebSocket
(
'
ws://www.host.com/path
'
);
ws
.
on
(
'
open
'
,
function
open
()
{
ws
.
send
(
'
something
'
);
});
ws
.
on
(
'
message
'
,
function
message
(
data
)
{
console
.
log
(
'
received: %s
'
,
data
);
});
```
### Sending binary data
```
js
import
WebSocket
from
'
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
import
{
WebSocketServer
}
from
'
ws
'
;
const
wss
=
new
WebSocketServer
({
port
:
8080
});
wss
.
on
(
'
connection
'
,
function
connection
(
ws
)
{
ws
.
on
(
'
message
'
,
function
message
(
data
)
{
console
.
log
(
'
received: %s
'
,
data
);
});
ws
.
send
(
'
something
'
);
});
```
### External HTTP/S server
```
js
import
{
createServer
}
from
'
https
'
;
import
{
readFileSync
}
from
'
fs
'
;
import
{
WebSocketServer
}
from
'
ws
'
;
const
server
=
createServer
({
cert
:
readFileSync
(
'
/path/to/cert.pem
'
),
key
:
readFileSync
(
'
/path/to/key.pem
'
)
});
const
wss
=
new
WebSocketServer
({
server
});
wss
.
on
(
'
connection
'
,
function
connection
(
ws
)
{
ws
.
on
(
'
message
'
,
function
message
(
data
)
{
console
.
log
(
'
received: %s
'
,
data
);
});
ws
.
send
(
'
something
'
);
});
server
.
listen
(
8080
);
```
### Multiple servers sharing a single HTTP/S server
```
js
import
{
createServer
}
from
'
http
'
;
import
{
parse
}
from
'
url
'
;
import
{
WebSocketServer
}
from
'
ws
'
;
const
server
=
createServer
();
const
wss1
=
new
WebSocketServer
({
noServer
:
true
});
const
wss2
=
new
WebSocketServer
({
noServer
:
true
});
wss1
.
on
(
'
connection
'
,
function
connection
(
ws
)
{
// ...
});
wss2
.
on
(
'
connection
'
,
function
connection
(
ws
)
{
// ...
});
server
.
on
(
'
upgrade
'
,
function
upgrade
(
request
,
socket
,
head
)
{
const
{
pathname
}
=
parse
(
request
.
url
);
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
import
WebSocket
from
'
ws
'
;
import
{
createServer
}
from
'
http
'
;
const
server
=
createServer
();
const
wss
=
new
WebSocketServer
({
noServer
:
true
});
wss
.
on
(
'
connection
'
,
function
connection
(
ws
,
request
,
client
)
{
ws
.
on
(
'
message
'
,
function
message
(
data
)
{
console
.
log
(
`Received message
${
data
}
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
,
function
next
(
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
import
WebSocket
,
{
WebSocketServer
}
from
'
ws
'
;
const
wss
=
new
WebSocketServer
({
port
:
8080
});
wss
.
on
(
'
connection
'
,
function
connection
(
ws
)
{
ws
.
on
(
'
message
'
,
function
message
(
data
,
isBinary
)
{
wss
.
clients
.
forEach
(
function
each
(
client
)
{
if
(
client
.
readyState
===
WebSocket
.
OPEN
)
{
client
.
send
(
data
,
{
binary
:
isBinary
});
}
});
});
});
```
A client WebSocket broadcasting to every other connected WebSocket clients,
excluding itself.
```
js
import
WebSocket
,
{
WebSocketServer
}
from
'
ws
'
;
const
wss
=
new
WebSocketServer
({
port
:
8080
});
wss
.
on
(
'
connection
'
,
function
connection
(
ws
)
{
ws
.
on
(
'
message
'
,
function
message
(
data
,
isBinary
)
{
wss
.
clients
.
forEach
(
function
each
(
client
)
{
if
(
client
!==
ws
&&
client
.
readyState
===
WebSocket
.
OPEN
)
{
client
.
send
(
data
,
{
binary
:
isBinary
});
}
});
});
});
```
### echo.websocket.org demo
```
js
import
WebSocket
from
'
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
message
(
data
)
{
console
.
log
(
`Roundtrip time:
${
Date
.
now
()
-
data
}
ms`
);
setTimeout
(
function
timeout
()
{
ws
.
send
(
Date
.
now
());
},
500
);
});
```
### Use the Node.js streams API
```
js
import
WebSocket
,
{
createWebSocketStream
}
from
'
ws
'
;
const
ws
=
new
WebSocket
(
'
wss://echo.websocket.org/
'
,
{
origin
:
'
https://websocket.org
'
});
const
duplex
=
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
import
{
WebSocketServer
}
from
'
ws
'
;
const
wss
=
new
WebSocketServer
({
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
import
{
WebSocketServer
}
from
'
ws
'
;
function
heartbeat
()
{
this
.
isAlive
=
true
;
}
const
wss
=
new
WebSocketServer
({
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
();
});
},
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
import
WebSocket
from
'
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
node_modules/ws/browser.js
0 → 100644
View file @
6d4909ed
'
use strict
'
;
module
.
exports
=
function
()
{
throw
new
Error
(
'
ws does not work in the browser. Browser clients must use the native
'
+
'
WebSocket object
'
);
};
node_modules/ws/index.js
0 → 100644
View file @
6d4909ed
'
use strict
'
;
const
WebSocket
=
require
(
'
./lib/websocket
'
);
WebSocket
.
createWebSocketStream
=
require
(
'
./lib/stream
'
);
WebSocket
.
Server
=
require
(
'
./lib/websocket-server
'
);
WebSocket
.
Receiver
=
require
(
'
./lib/receiver
'
);
WebSocket
.
Sender
=
require
(
'
./lib/sender
'
);
WebSocket
.
WebSocket
=
WebSocket
;
WebSocket
.
WebSocketServer
=
WebSocket
.
Server
;
module
.
exports
=
WebSocket
;
node_modules/ws/lib/buffer-util.js
0 → 100644
View file @
6d4909ed
'
use strict
'
;
const
{
EMPTY_BUFFER
}
=
require
(
'
./constants
'
);
/**
* Merges an array of buffers into a new buffer.
*
* @param {Buffer[]} list The array of buffers to concat
* @param {Number} totalLength The total length of buffers in the list
* @return {Buffer} The resulting buffer
* @public
*/
function
concat
(
list
,
totalLength
)
{
if
(
list
.
length
===
0
)
return
EMPTY_BUFFER
;
if
(
list
.
length
===
1
)
return
list
[
0
];
const
target
=
Buffer
.
allocUnsafe
(
totalLength
);
let
offset
=
0
;
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
)
{
const
buf
=
list
[
i
];
target
.
set
(
buf
,
offset
);
offset
+=
buf
.
length
;
}
if
(
offset
<
totalLength
)
return
target
.
slice
(
0
,
offset
);
return
target
;
}
/**
* Masks a buffer using the given mask.
*
* @param {Buffer} source The buffer to mask
* @param {Buffer} mask The mask to use
* @param {Buffer} output The buffer where to store the result
* @param {Number} offset The offset at which to start writing
* @param {Number} length The number of bytes to mask.
* @public
*/
function
_mask
(
source
,
mask
,
output
,
offset
,
length
)
{
for
(
let
i
=
0
;
i
<
length
;
i
++
)
{
output
[
offset
+
i
]
=
source
[
i
]
^
mask
[
i
&
3
];
}
}
/**
* Unmasks a buffer using the given mask.
*
* @param {Buffer} buffer The buffer to unmask
* @param {Buffer} mask The mask to use
* @public
*/
function
_unmask
(
buffer
,
mask
)
{
for
(
let
i
=
0
;
i
<
buffer
.
length
;
i
++
)
{
buffer
[
i
]
^=
mask
[
i
&
3
];
}
}
/**
* Converts a buffer to an `ArrayBuffer`.
*
* @param {Buffer} buf The buffer to convert
* @return {ArrayBuffer} Converted buffer
* @public
*/
function
toArrayBuffer
(
buf
)
{
if
(
buf
.
byteLength
===
buf
.
buffer
.
byteLength
)
{
return
buf
.
buffer
;
}
return
buf
.
buffer
.
slice
(
buf
.
byteOffset
,
buf
.
byteOffset
+
buf
.
byteLength
);
}
/**
* Converts `data` to a `Buffer`.
*