forked from vasanthv/hello
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
executable file
·174 lines (144 loc) · 5.08 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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
"use strict"; // https://www.w3schools.com/js/js_strict.asp
const ngrok = require("ngrok");
const express = require("express");
const path = require("path");
const http = require("http");
const app = express();
const server = http.createServer(app);
const io = require("socket.io")(server);
const util = require("util");
// util options
const options = {
depth: null,
colors: true,
};
// Server all the static files from www folder
app.use(express.static(path.join(__dirname, "www")));
app.use(express.static(path.join(__dirname, "icons")));
app.use(express.static(path.join(__dirname, "node_modules/vue/dist/")));
// Get PORT from env variable else assign 3000 for development
const PORT = process.env.PORT || 3000;
// Get NGROK_AUTH_TOKEN from env variable: https://ngrok.com
const NGROK_AUTH_TOKEN = process.env.NGROK_AUTH_TOKEN || "";
server.listen(PORT, null, () => {
// On default not set
if (NGROK_AUTH_TOKEN) {
ngrokStart();
} else {
console.log("Server", {
listening_on: "http://localhost:" + PORT,
node_version: process.versions.node,
});
}
});
/**
* Expose Server to external with https tunnel using ngrok:
* https://www.npmjs.com/package/ngrok
*/
async function ngrokStart() {
try {
await ngrok.authtoken(NGROK_AUTH_TOKEN);
await ngrok.connect(PORT);
let api = ngrok.getApi();
let data = await api.listTunnels();
let pu0 = data.tunnels[0].public_url;
let pu1 = data.tunnels[1].public_url;
let tunnelHttps = pu0.startsWith('https') ? pu0 : pu1;
// Server settings
console.log('Server', {
listen_on: "http://localhost:" + PORT,
tunnel_https: tunnelHttps,
node_version: process.versions.node,
});
} catch (err) {
console.warn('Error ngrokStart', err.body);
process.exit(1);
}
}
app.get("/legal", (req, res) => res.sendFile(path.join(__dirname, "www/legal.html")));
// All URL patterns should served with the same file.
app.get(["/", "/:room"], (req, res) => res.sendFile(path.join(__dirname, "www/index.html")));
const channels = {};
const sockets = {};
const peers = {};
io.sockets.on("connection", (socket) => {
const socketHostName = socket.handshake.headers.host.split(":")[0];
socket.channels = {};
sockets[socket.id] = socket;
console.log("[" + socket.id + "] connection accepted");
socket.on("disconnect", () => {
for (const channel in socket.channels) {
part(channel);
}
console.log("[" + socket.id + "] disconnected");
delete sockets[socket.id];
});
socket.on("join", (config) => {
console.log("[" + socket.id + "] join ", config);
const channel = socketHostName + config.channel;
// Already Joined
if (channel in socket.channels) return;
if (!(channel in channels)) {
channels[channel] = {};
}
if (!(channel in peers)) {
peers[channel] = {};
}
peers[channel][socket.id] = {
userData: config.userData,
};
console.log("[" + socket.id + "] join - connected peers grouped by channel", util.inspect(peers, options));
for (const id in channels[channel]) {
channels[channel][id].emit("addPeer", { peer_id: socket.id, should_create_offer: false, channel: peers[channel] });
socket.emit("addPeer", { peer_id: id, should_create_offer: true, channel: peers[channel] });
}
channels[channel][socket.id] = socket;
socket.channels[channel] = channel;
});
socket.on("updateUserData", async (config) => {
const channel = socketHostName + config.channel;
const key = config.key;
const value = config.value;
for (let id in peers[channel]) {
if (id == socket.id) {
peers[channel][id]["userData"][key] = value;
}
}
console.log("[" + socket.id + "] updateUserData", util.inspect(peers[channel][socket.id], options));
});
const part = (channel) => {
// Socket not in channel
if (!(channel in socket.channels)) return;
delete socket.channels[channel];
delete channels[channel][socket.id];
delete peers[channel][socket.id];
if (Object.keys(peers[channel]).length == 0) {
// last peer disconnected from the channel
delete peers[channel];
}
console.log("[" + socket.id + "] part - connected peers grouped by channel", util.inspect(peers, options));
for (const id in channels[channel]) {
channels[channel][id].emit("removePeer", { peer_id: socket.id });
socket.emit("removePeer", { peer_id: id });
}
};
socket.on("relayICECandidate", (config) => {
let peer_id = config.peer_id;
let ice_candidate = config.ice_candidate;
console.log("[" + socket.id + "] relay ICE-candidate to [" + peer_id + "] ", ice_candidate);
if (peer_id in sockets) {
sockets[peer_id].emit("iceCandidate", { peer_id: socket.id, ice_candidate: ice_candidate });
}
});
socket.on("relaySessionDescription", (config) => {
let peer_id = config.peer_id;
let session_description = config.session_description;
console.log("[" + socket.id + "] relay SessionDescription to [" + peer_id + "] ", session_description);
if (peer_id in sockets) {
sockets[peer_id].emit("sessionDescription", {
peer_id: socket.id,
session_description: session_description,
});
}
});
});