Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F101444877
README.md
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Feb 10, 13:22
Size
14 KB
Mime Type
text/x-java
Expires
Wed, Feb 12, 13:22 (2 d)
Engine
blob
Format
Raw Data
Handle
24147182
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
README.md
View Options
#
ws
:
a
Node
.
js
WebSocket
library
[![
Version
npm
](
https
:
//img.shields.io/npm/v/ws.svg?logo=npm)](https://www.npmjs.com/package/ws)
[![
CI
](
https
:
//img.shields.io/github/actions/workflow/status/websockets/ws/ci.yml?branch=master&label=CI&logo=github)](https://github.com/websockets/ws/actions?query=workflow%3ACI+branch%3Amaster)
[![
Coverage
Status
](
https
:
//img.shields.io/coveralls/websockets/ws/master.svg?logo=coveralls)](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
)
-
[
Round
-
trip
time
](#
round
-
trip
-
time
)
-
[
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
that
improve
the
performance
of
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
.
To
not
even
try
to
require
and
use
these
modules
,
use
the
[
`WS_NO_BUFFER_UTIL`
](./
doc
/
ws
.
md
#
ws_no_buffer_util
)
and
[
`WS_NO_UTF_8_VALIDATE`
](./
doc
/
ws
.
md
#
ws_no_utf_8_validate
)
environment
variables
.
These
might
be
useful
to
enhance
security
in
systems
where
a
user
can
put
a
package
in
the
package
search
path
of
an
application
of
another
user
,
due
to
how
the
Node
.
js
resolver
algorithm
works
.
The
`utf-8-validate`
module
is
not
needed
and
is
not
required
,
even
if
it
is
already
installed
,
regardless
of
the
value
of
the
`WS_NO_UTF_8_VALIDATE`
environment
variable
,
if
[
`buffer.isUtf8()`
][]
is
available
.
##
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
{
createServer
}
from
'
http
'
;
import
{
WebSocketServer
}
from
'
ws
'
;
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
});
}
});
});
});
```
###
Round
-
trip
time
```
js
import
WebSocket
from
'
ws
'
;
const
ws
=
new
WebSocket
(
'
wss
:
//websocket-echo.com/');
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
(
`Round-trip 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
:
//websocket-echo.com/');
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
:
//websocket-echo.com/');
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
)
[
`buffer.isutf8()`
]:
https
:
//nodejs.org/api/buffer.html#bufferisutf8input
[
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
]:
./
doc
/
ws
.
md
#
new
-
websocketserveroptions
-
callback
Event Timeline
Log In to Comment