-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
132 lines (113 loc) · 2.98 KB
/
server.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
const express = require('express');
const http = require('http');
const ws = require('ws');
/**
* Websocket server wrapper
*/
class Server {
constructor(sapling) {
this.sapling = sapling;
this.setup();
}
/**
* Gets sapling instance
*
* @returns {Sapling}
*/
getSapling() {
return this.sapling;
}
/**
* Setup our servers
*
* An existing express, HTTP server and/or Websocket server
* instances can be passed when Sapling is constructed as an option
*/
setup() {
this.express = this.sapling.getOpts().express || express();
this.http = this.sapling.getOpts().http || http.createServer(this.express);
this.ws = this.sapling.getOpts().ws || new ws.Server({ server : this.http });
// for existing HTTP server instances, make sure we're not listening
if (!this.http.listening) {
this.http.listen(this.sapling.getOpts().port || 8080);
}
// register websocket events
this.setupEvents();
}
/**
* Register Websocket events
*/
setupEvents() {
this.ws.on('connection', this._onClientConnect.bind(this));
}
/**
* When a client connects to the websocket
*
* @param {Client} client
*/
_onClientConnect(client) {
client.sendJSON = (data) => {
client.send(JSON.stringify(data));
};
this.sapling.getEvents().emit('clientConnect', client);
client.on('message', (str => {
this._onClientMessage.bind(this)(str, client);
}).bind(this));
client.on('close', (code => { this._onClientClose(client, code); }).bind(this));
client.on('error', (err => { this._onClientError(client, err); }).bind(this));
}
/**
* When a client disconnects from the websocket
*
* @param {Client} client
*/
_onClientClose(client, code) {
this.sapling.getEvents().emit('clientClose', client, code);
}
/**
* When a client disconnects from the websocket
*
* @param {Client} client
*/
_onClientError(client, err) {
this.sapling.getEvents().emit('clientError', client, err);
}
/**
* When a client sends a message
*
* @param {String} str message
* @param {Client} client
*/
_onClientMessage(str, client) {
this.sapling.getEvents().emit('clientMessage', client, str);
const response = JSON.stringify(this.parseMessage(str, client));
if (client.readyState === ws.OPEN)
client.send(response);
else {
console.log(`Cannot send ${response} to client, lost connection`);
}
}
/**
* Parses a client message, and find its route
*
* @param {String} str message
* @returns {Object} object response results
*/
parseMessage(str, client) {
var resp = { error: true, message: 'Invalid request made' };
try {
// try to parse message
var json = JSON.parse(str);
if (null === json || !(json instanceof Object) || !json.action) {
return resp;
}
// find route bruh!
resp = this.sapling.findRoute(json.action, {raw: json, client}).res;
} catch (e) {
console.log('[!] Error! ', e);
resp.message = 'Internal server error, ' + e;
}
return resp;
}
}
module.exports = Server;