-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsocket.js
113 lines (92 loc) · 4.29 KB
/
socket.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
const io = require('socket.io')(process.env.PORT || "8080");
const logger = require('./Logger');
const SecretConnector = require('./connectors/SecretConnector');
const RedisConnector = require('./connectors/RedisConnector');
const NotificationConnector = require('./connectors/NotificationConnector');
const TimerDSConnector = require('./connectors/datastore/TimerDSConnector');
const TimerHandler = require('./handlers/TimerHandler');
const AuthHandler = require('./handlers/AuthHandler');
// Format: OfficeID : AmountOfClients
const _clientsPerOffice = new Map();
const main = async () => {
// Setup our core connectors
await SecretConnector.setup(); // This MUST BE FIRST as it provides keys for our services
await RedisConnector.setup();
await NotificationConnector.setup();
await TimerDSConnector.setup();
// Setup Handlers
await AuthHandler.setup();
//
// Handle daemon exit
registerExitHandlers();
io.on('connection', socket => {
console.log(`Socket ${socket.id} connected! IP: ${socket.handshake.headers['x-forwarded-for'] || socket.handshake.address}`);
// Authentication
setTimeout(() => {
if (!socket.office) {
logger.info(`Socket ${socket.id} auth timed out!`);
socket.emit('auth-error', 'Session timeout');
socket.disconnect();
}
}, 5000);
socket.once('auth', async (token) => {
const authenticated = await AuthHandler.handleAuth(socket, token);
if (authenticated) {
// Get our count of clients connected to this clients office
let currentOfficeAmount = _clientsPerOffice.get(socket.office);
// We dont have any clients with this office yet, lets subscribe!
if (typeof currentOfficeAmount === "undefined") {
_clientsPerOffice.set(socket.office, 1);
logger.info("Subscribing to office " + socket.office);
await RedisConnector.subToTopic(socket.office);
} else {
_clientsPerOffice.set(socket.office, currentOfficeAmount + 1);
}
registerListeners(socket);
await AuthHandler.postAuth(socket);
}
}
);
socket.once('disconnect', () => {
logger.info(`Socket ${socket.id} disconnected.`);
// If the client was authenticated
if (socket.office) {
const officeNum = socket.office;
const newOfficeCount = _clientsPerOffice.get(officeNum) - 1;
RedisConnector.adjustClientCount(officeNum, -1);
if (newOfficeCount <= 0) {
logger.debug("Client is the last of the office. Unsubbing...");
_clientsPerOffice.delete(officeNum);
RedisConnector.removeTopic(officeNum);
} else {
logger.debug("Reducing client count by 1 as others in the same office are still connected.");
_clientsPerOffice.set(officeNum, newOfficeCount);
}
}
});
socket.emit('auth.request');
}
);
};
const registerListeners = (socket) => {
socket.on('clock.get', () => socket.emit('clock.status', new Date().getTime()));
socket.on('timer.reset', (timerID) => TimerHandler.handleReset(socket, timerID));
socket.on('timer.zero', (timerID) => TimerHandler.handleZero(socket, timerID));
socket.on('timer.delete', (timerID) => TimerHandler.handleDelete(socket, timerID));
socket.on('timer.create', (data) => TimerHandler.handleCreate(socket, data));
};
const registerExitHandlers = () => {
const exitHandler = ()=>{
io.close(() => {
process.exit();
});
};
process.stdin.resume();
process.on('exit', exitHandler);
process.on('SIGINT', exitHandler);
process.on('SIGUSR1', exitHandler);
process.on('SIGUSR2', exitHandler);
process.on('uncaughtException', exitHandler);
};
main();
module.exports = io;