-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
102 lines (82 loc) · 2.77 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
const express = require('express');
const path = require('path');
const get = require('lodash/get');
const enableKafka = require('./backend/kafka/index');
const randomLogin = require('./backend/nicknames/generator');
const defaultPort = 8080;
function getPort() {
return (
process.argv
.filter(a => a.startsWith('port'))
.map(val => Number(val.split(/[ =]+/g)[1] || defaultPort))
.pop() || defaultPort
);
}
const port = getPort(); // should be possible to overide the port via console arg
const v = 11; // indicating app version from kubernetes logs
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
app.use(express.static('build/public'));
app.get('/api', (req, res) => res.json(process.env)); // test rest api
// as we don't have separate persistance service (like redis) we have to introduce local state <- which is not good.
// With stateless services everything is simpler!
const set = new Set();
if (process.env.KAFKA_ENABLED === 'true') {
const emitter = enableKafka(io);
emitter.on('kafkaIncome', msg => {
const data = get(JSON.parse(msg.value), 'packet.data', []);
if (data[0] === 'userConnected') {
set.add(data[1]);
}
if (data[0] === 'userDisconnected') {
set.delete(data[1]);
}
});
}
function getUserName(socket) {
const cookie = get(socket, 'handshake.headers.cookie', '');
const check = cookie.split(/\s*;\s*/).find(c => c.startsWith('check'));
if (!check) {
return randomLogin();
}
const parts = check.split('^');
if (!parts.length === 2) {
return randomLogin();
}
const userData = parts[1].split('|');
if (!userData.length === 4) {
return randomLogin();
}
return `${decodeURIComponent(userData[1])}_${decodeURIComponent(userData[2])} (${userData[0]})`;
}
/** Chat Websocket logic is here */
const chat = io.of('/api/chat').on('connection', socket => {
const nick = getUserName(socket);
set.add(nick);
socket.emit('message', { msg: `Welcome #${nick}`, currUserId: nick });
socket.emit('activeUsers', Array.from(set));
socket.broadcast.emit('message', { msg: `${nick} connected to the chat` });
chat.emit('userConnected', nick);
socket.on('message', msg => {
console.log(`message: ${msg}`);
const time = new Date();
chat.emit('message', {
msg,
user: nick,
time: `${time.getHours()}:${time.getMinutes()}`,
});
});
socket.on('disconnect', () => {
set.delete(nick);
chat.emit('userDisconnected', nick);
chat.emit('message', { msg: `~ ${nick} disconnected` });
console.log('Client disconnected');
});
});
app.get('*', (req, res) => {
const fileDirectory = path.resolve(__dirname, '.', 'public/');
res.sendFile('index.html', { root: fileDirectory });
});
/* Run the application */
server.listen(port, () => console.log('Chat server started...', { port, v }));