- No permessage-deflate.
- No integrated support TLS/SSL for both client sockets and server.
- Minimum node.js version is v6.4.0 - it uses classes and rest parameters.
Socket.onmessage
has either aBuffer
and aString
as the message.- It's built only for the RFC6455 protocol specification.
- Only one event handler per event is allowed.
- Events can be set by calling
on
oronce
or by settingonX
(ex.onmessage = handler
). - The
Server
class doesn't track connections, so:- Broadcasting isn't supported.
- Closing the HTTP server doesn't close active connections.
- Closing a socket will not automatically trigger the
close
event. It will wait for the other peer's response (close opcode message or explicit FIN) and then emit it.
const MiniWS = require("miniws");
The WebSocket server implementation that accepts incoming HTTP connections. Uses the http
module internally unless specified as the option during construction.
const MiniWS = require("miniws");
const echoServer = new MiniWS.Server({
port: 1337
});
echoServer.on("connection", function(ws) {
ws.on("message", function(data) {
console.log(`Server got "${data}"`);
ws.send(data);
});
});
echoServer.start();
const myServer = new MiniWS.Server({
host: "0.0.0.0",
port: 80,
backlog: 511,
httpServer: undefined,
verifyConnection: function(remoteAddress, origin, extensions, subprotocols, request) {
// Your magic goes here
return true;
},
getSubprotocol: function(subprotocols, extensions, remoteAddress, origin, request) {
// Your magic goes here
return subprotocols[0] || null;
}
});
options
(Object
)options.host
(String?
) The bind address for the HTTP server. Defaults to0.0.0.0
.options.port
(Number?
) The bind port for the HTTP server. Defaults to80
.options.backlog
(Number?
) The maximum count of pending connections. Defaults to511
.options.httpServer
(http.Server
orhttps.Server
) The object to use as the HTTP server. If unspecified an internal defaulthttp.Server
is used.options.verifyConnection
(Function?
returningBoolean
) If specified, it's synchronously called after checking the headers of the incoming request. If it returnsfalse
, the server responds with 403 Forbidden, thereby saving a little in bandwidth.remoteAddress
(String
) Remote address of the incoming connection.origin
(String
) The origin given in the headers, if any.extensions
(ExtensionObject
) The extensions given.subprotocols
(String[]
) An array consisting of requested subprotocols.request
(http.IncomingMessage
) The request itself.
options.getSubProtocol
(Function?
returningString
) If specifed, it's called afteroptions.verifyConnection
in case a subprotocol was requested. Note that it has the same arguments asoptions.verifyConnection
albeit in a different order. The return value will be set as the subprotocol for the response.
callback
(Function?
) Optional. Internally calls.start(callback)
immediately after finishing construction.
An example mux; max-channels=4; flow-control, deflate-stream, application-extension; version="1.1.4"
is in this form:
{
"application-extension": {
"version": "1.1.4"
},
"deflate-stream": { },
"mux": {
"max-channels": 4,
"flow-control": true
}
}
myServer.start(function() {
console.log("Listening");
// Your magic goes here
});
callback
(Function?
) Optional. Called when the underlying HTTP server fully opens.
Starts the underlying HTTP server.
callback
(Function?
) Optional. Called when the underlying HTTP server fully closes.
Stops the underlying HTTP server.
Arguments:
newSocket
(MiniWS.Socket
) The new upgraded connection.
Called on a successful WebSocket upgrade.
var connection = MiniWS.createClient("ws://127.0.0.1:80");
connection.on("response", function(response) {
// Check for an useless header, why the heck not!
if (response.headers["x-wantstoconnectwithsomeone"] !== "yes")
connection.abort();
});
connection.on("open", function() {
connection.send("I don't want to connect with you");
connection.close(1006, "So goodbye");
});
Available only on client-side connections.
connection.on("response", function(response) {
if (somethingChanged)
// .abort() signals the request to be destroyed.
connection.abort();
});
response
(http.IncomingMessage
) The response the remote HTTP server sent.
Called immediately after the response has been received. It allows a final, synchronous check `
Available only on client-side connections.
connection.on("open", function() {
console.log("I'm connected");
// Your magic goes here
});
Emitted when the upgrade finishes.
Available in both types of connections.
connection.on("error", function(err) {
connection.close(1001, "Plz no gib errors");
});
Emitted either when the client-side upgrade gets rejected or an unavoidable protocol error gets caught. If no event handler is set the error gets thrown and will not be caught internally.
Available in both types of connections.
connection.on("open", function(info) {
console.log(`I'm disconnected (code ${event.code} reason ${event.reason}`);
// Your magic goes here
});
info
(Object
)info.code
(Number
) The specified close code.info.reason
(String
) If any, the close reason.
Emitted when a FIN-ended close message is received. If the implementation isn't the one who sent the close frame first, it will immediately attempt echoing the close code after the event has been processed. Any write attempts (.ping
, .send
and .close
) will throw an error.
Available in both types of connections.
connection.on("message", function(message) {
// Your magic goes here
});
message
(String
orBuffer
) The message itself. In the case of aBuffer
, it is not cloned.
Emitted when a FIN-ended text or binary message is received. If it's a text message, it's turned into a String
.
Available in both types of connections.
connection.on("ping", function(message) {
console.log("I was pinged");
});
message
(Buffer
) The payload of the message. If none, it is a zero-lengthBuffer
.
Emitted when a FIN-ended ping message is received. The implementation will immediately attempt sending a pong frame after this event has been processed.
Available in both types of connections.
var pingedOn = Date.now();
connection.ping();
connection.on("pong", function(message) {
var latency = Date.now() - pingedOn;
console.log(`My latency is ${latency}ms`);
});
message
(Buffer
) The message sent with.ping
, echoed. If none, it is a zero-lengthBuffer
.
Emitted when a FIN-ended pong message is received.
Available in both types of connections.
sqlHandle.log("connection", newConnection.remoteAddress, Date.now());
- Returns
String
Returns the IP address of the remote peer.
Available in both types of connections.
if (connection.state === MiniWS.Socket.CLOSED)
throw new Error("Why are you closed??????");
- Returns
Number
Possible values are0
forCLOSED
,1
forCONNECTING
and2
forOPEN
.
Indicates the state of the connection.
If the state is CLOSED
, write operations (.ping
, .send
, .abort
) are going to throw upon calling.
If the state is CONNECTING
, .abort
can be called once. See MiniWS.createClient
for more details.
If the state is OPEN
, .ping
and .send
can be called until .close
gets called or the remote peer ends the connection. .abort
will throw.
Available in both types of connections.
connection.ping(Buffer.from("Extra data", "utf-8"));
data
(Buffer?
) An optional message payload to send.
Sends a ping frame to the remote end.
Available in both types of connections.
connection.on("open", function() {
connection.send("Test");
});
data
(Buffer
, a typed array,ArrayBuffer
orString
) The data to send.
Sends a text or binary frame to the remote end, depending on the argument type.
Available in both types of connections.
connection.on("message", function(data) {
if (typeof data === "string")
connection.close(4000, "String message is not accepted");
});
code
(Number?
) The close code. Defaults to 1000.reason
(String?
) The close reason. Defaults to an empty string.
Sends a close frame to the remote end.
This does not end the readable side of the socket, and so the close
event will not be called immediately. The state will still be OPEN
until the remote end echoes the close code back, however any write attempts (.ping
, .send
and repeating .close
) will throw an error.
Available only on client-side connections.
connection.on("response", function(response) {
if (!isValidResponse(response))
connection.abort();
});
If the state is CONNECTING
, it signals the underlying HTTP request to not create a connection and to close the connection.
This class is exposed along with MiniWS.Server
, however it has no actual functionality by itself. It's merely a wrapper for a net.Socket
. It must be fed with a socket after constructing it to get it working. It can be used for wrapping sockets got by different connection handshakes. Although I do not endorse that I will give out help for using the class separately. The basics are:
var explicitWebSocket = new MiniWS.Socket();
/*
The default state for it is CLOSED.
Both send and close operations throw errors.
HOWEVER, if you preemptively return the object and it's client-side,
setting _state to MiniWS.Socket.CONNECTING enables calling .abort().
.abort() sets the state back to CLOSED so it can be checked for later
if connecting gets cancelled.
*/
explicitWebSocket._state = MiniWS.Socket.CONNECTING;
/*
Enable send and close operations, and with that data transmit by calling _open.
After calling ._open(), the .abort() method will throw.
*/
explicitWebSocket._open(/* net.Socket */, /* surpress emitting onOpen */, /* first data buffer, if any */);
/*
If necessary, set _writer_mask to true to send masked data.
This is disabled by default too.
*/
explicitWebSocket._writer_mask = true;
/*
If you need to close the socket without using the WebSocket protocol,
call ._close(null, true).
*/
explicitWebSocket._close(null, true);
var client = MiniWS.createClient("ws://127.0.0.1:80/");
client.on("open", function() {
client.on("message", function(data) {
console.log(`Client got "${data}"`);
client.close(1000);
})
client.send("Test");
})
url
(String
) The URL to connect to.options
(Object
)subprotocols
(String[]?
) The subprotocols to request.headers
(Object?
) Additional headers to add to the request, if any.localAddress
(String?
) The local interface to connect from.family
(Number?
) IP address family to use. If unspecified both will be used.
- Returns
MiniWS.Socket
This function creates an HTTP GET request and returns a WebSocket in CONNECTING
state. If the request gets rejected with any other status code other than 101 Switching Protocols
an error gets thrown (see the error event). Otherwise it switches to OPEN
state and the open
event gets emitted.