-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
118 lines (101 loc) · 3.02 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* WebSocket Adapter
* @module adapters/ws
*/
'use strict';
/* Requires ------------------------------------------------------------------*/
const isBrowser = (typeof WebSocket !== 'undefined');
const ws = isBrowser ? WebSocket : require('uws');
/* Local variables -----------------------------------------------------------*/
const send_options = { binary: true };
/* Methods -------------------------------------------------------------------*/
/**
* Converts ArrayBuffers to Buffers (cycle)
* @private
* @param {ArrayBuffer} ab The ArrayBuffer to convert
* @returns {Buffer} The resulting Buffer
*/
function _abToBuffer(ab) {
return ab.data || new Uint8Array(ab);
}
/**
* Listens for WebSocket connections on the selected port.
* @param {Server} server The Kalm Server reference
* @param {function} callback The success callback for the operation
*/
function listen(handlers, options) {
const listener = new ws.Server({ port: options.port });
listener.on('connection', handlers.handleConnection);
listener.on('error', handlers.handleError);
return Promise.resolve(listener);
}
/**
* Sends a message with a socket client
* @param {Socket} socket The socket to use
* @param {Buffer} payload The body of the request
*/
function send(socket, payload) {
if (socket.sendBytes) socket.sendBytes(payload);
else socket.send(payload, send_options);
}
/**
* Stops listening for WebSocket connections and closes the Server.
* @param {Server} server The Kalm Server reference
* @param {function} callback The success callback for the operation
*/
function stop(server, callback) {
server.listener.close();
setTimeout(callback, 0);
}
/**
* Creates a client
* @param {Client} client The client to create the socket for
* @returns {Socket} The created WebSocket client
*/
function createSocket(client) {
const socket = new ws(`ws://${client.hostname}:${client.port}`);
if (!isBrowser) socket.binaryType = 'nodebuffer';
socket.__pending = true;
return socket;
}
function getOrigin(socket) {
return {
host: socket._socket.remoteAddress,
port: socket._socket.remotePort
};
}
function attachSocket(socket, handlers) {
if (isBrowser) {
socket.onmessage = evt => handlers.handleRequest(_abToBuffer(evt.data));
socket.onerror = handlers.handleError;
socket.onclose = handlers.handleDisconnect;
socket.onopen = handlers.handleConnect;
}
else {
socket.on('message', evt => handlers.handleRequest(_abToBuffer(evt)));
socket.on('error', handlers.handleError);
socket.on('close', handlers.handleDisconnect);
if (socket.__pending) {
delete socket.__pending;
socket.on('open', handlers.handleConnect);
}
}
}
/**
* Attempts to disconnect the socket
* @param {Socket} socket The socket to disconnect
*/
function disconnect(client, callback) {
client.socket.close();
setTimeout(callback, 0);
}
/* Exports -------------------------------------------------------------------*/
module.exports = {
listen,
send,
createSocket,
attachSocket,
getOrigin,
stop,
disconnect
};