-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathserver.js
156 lines (137 loc) · 3.87 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
'use strict';
const express = require('express');
const app = express();
const CONFIG = require('./config.json');
const wss = new (require('ws').Server)(
{
host: '::',
port: CONFIG.WEBSOCKET_PORT,
},
function () {
console.log(
'Websocket server listening on port ' + CONFIG.WEBSOCKET_PORT + '...'
);
}
);
const sendHeartbeats = require('ws-heartbeats');
// Page Constants
const PAGE_DRAW = 'draw';
const PAGE_CONTROL = 'control';
const PAGE_RENDER = 'render';
// Command Constants
const COMMAND_UP = 'UP';
const COMMAND_DOWN = 'DOWN';
const COMMAND_COLOR = 'COLOR';
const COMMAND_SIZE = 'SIZE';
app.use('/draw', express.static(__dirname + '/draw.html'));
app.use('/control', express.static(__dirname + '/control.html'));
app.use('/render', express.static(__dirname + '/render.html'));
app.use('/', express.static(__dirname));
app.all('*', function (req, res) {
res.redirect('/');
});
app.listen(CONFIG.WEBSERVER_PORT, function () {
console.log('Web server started on port ' + CONFIG.WEBSERVER_PORT + '...');
});
const socketsDraw = [];
const socketsControl = [];
const socketsRender = [];
let tempCanvas = CONFIG.DEFAULT_CANVAS;
let status, color, size;
// Sends the stringified message object over the given websocket
function stringSend(socket, msg) {
socket.send(JSON.stringify(msg));
}
// Sends the data to all pages of the given type
function socketSend(page, data) {
let workingSockets = [];
switch (page) {
case PAGE_DRAW:
workingSockets = socketsDraw;
break;
case PAGE_CONTROL:
workingSockets = socketsControl;
break;
case PAGE_RENDER:
workingSockets = socketsRender;
break;
}
workingSockets.forEach(function (sock) {
stringSend(sock, data);
});
}
wss.on('connection', function connection(ws, req) {
const page = req.url.substring(1); // see who connected
let place = -1;
// Add current connection to the correct pool based on page type
switch (page) {
case PAGE_DRAW:
place = socketsDraw.push(ws);
break;
case PAGE_CONTROL:
place = socketsControl.push(ws);
break;
case PAGE_RENDER:
place = socketsRender.push(ws);
break;
}
console.log(page + ' ' + --place + ' connected');
// Keep websocket connection alive
sendHeartbeats(ws, { heartbeatTimeout: 30000, heartbeatInterval: 10000 });
// Send current configuration and canvas to new connections
if (color) {
stringSend(ws, color);
}
if (size) {
stringSend(ws, size);
}
if (page === PAGE_DRAW || page === PAGE_CONTROL) {
stringSend(ws, tempCanvas);
if (status) {
stringSend(ws, status);
} else {
stringSend(ws, { command: COMMAND_DOWN });
}
} else if (status && status.command === COMMAND_DOWN) {
stringSend(ws, tempCanvas);
}
ws.on('message', function incoming(rawData) {
const data = JSON.parse(rawData);
let message = '';
switch (data.command) {
case COMMAND_DOWN: // going off air
case COMMAND_UP: // going on air
status = data; // keep track of the status
break;
case COMMAND_COLOR:
color = data;
break;
case COMMAND_SIZE:
size = data;
break;
default:
// sending a canvas
tempCanvas = data; // keep track of the canvas
message = 'received canvas update';
}
message = message !== '' ? message : "received '" + rawData + "'";
console.log((message += ' from ' + page + ' ' + place));
socketSend(PAGE_DRAW, data);
socketSend(PAGE_CONTROL, data);
socketSend(PAGE_RENDER, data);
});
ws.on('close', function () {
switch (page) {
case PAGE_DRAW:
delete socketsDraw[place];
break;
case PAGE_CONTROL:
delete socketsControl[place];
break;
case PAGE_RENDER:
delete socketsRender[place];
break;
}
console.log(page + ' ' + place + ' disconnected');
});
});