forked from manav2401/video-calling
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
257 lines (200 loc) · 6.43 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
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
// grabbing the packages
const express = require('express');
const WebSocket = require('ws');
const http = require('http');
const path = require('path');
// app variables
var app = null;
var httpServer = null;
var webSockerServer = null;
var clientId = 0;
var msg = null;
// maintaining the connections array to track client connections
var connections = [];
const PORT = 5000;
// function to log by timestamp
function log(text) {
var time = new Date();
console.log("[" + time.toLocaleTimeString() + "] [Server]" + text);
}
// create an express app object
app = express();
// creating http server and passing the express app object
httpServer = http.createServer(app);
// allow the app to load static content
app.use(express.static(path.join(__dirname, "./public")));
// defining the '/' route for loading the base index.html file
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, "./public/index.html"));
})
// starting the server, listening on `PORT` port.
httpServer.listen(PORT, () => {
console.log('Server listening on http://localhost:' + PORT);
})
// creating a new websocket server
webSockerServer = new WebSocket.Server({
server: httpServer
});
if (!webSockerServer) {
log('ERROR: Unable to create websocet server');
}
// on connection listener
webSockerServer.on('connection', function (ws) {
// connection has websocket object and ID assigned of the client
var connection = {};
connection.webSocket = ws;
connection.clientId = clientId;
connection.status = 'available';
log('Client connected. ID: ' + clientId);
clientId++;
// add the object to the array
connections.push(connection);
// send the client with it's assigned client id
msg = {
type: "id",
id: connection.clientId
};
ws.send(JSON.stringify(msg));
// on message listner
ws.on('message', function (message) {
// parse the message to json
var messageReceived = JSON.parse(message);
// store client id
if (messageReceived.type === 'normal') {
log(messageReceived.message + " from " + messageReceived.id);
}
// message when caller offers a call to the callee
if (messageReceived.type === 'video-offer-request') {
var i;
var callee = null;
var isAvailable = true;
// find the corresponding callee from the array
for (i = 0; i < connections.length; i++) {
if (messageReceived.calleeId === connections[i].clientId) {
callee = connections[i].webSocket;
// check availability only for 1st iteration
if (Number(messageReceived.iteration) === Number(1)) {
if (connections[i].status === 'busy') {
isAvailable = false;
}
}
break;
}
}
if (isAvailable == true && callee != null) {
// client is available
// send the message to corresponding callee
msg = {
type: "video-answer-request",
callerId: messageReceived.id,
offer: messageReceived.offer
}
callee.send(JSON.stringify(msg));
} else if (isAvailable == false && callee != null) {
// client is busy
msg = {
type: "client-busy",
message: "client is busy.",
calleeId: messageReceived.calleeId
}
ws.send(JSON.stringify(msg));
} else {
// send error message
msg = {
type: "non-existing-client",
calleeId: messageReceived.calleeId,
message: "Callee ID " + messageReceived.calleeId + " doesn't exist."
}
ws.send(JSON.stringify(msg));
}
}
// receives the response of the call offer from callee
if (messageReceived.type === 'client-reply') {
var i;
var caller = null;
// find the corresponding caller from the array
for (i = 0; i < connections.length; i++) {
if (messageReceived.callerId === connections[i].clientId) {
caller = connections[i].webSocket;
if (messageReceived.reply === "1") {
connections[i].status = 'busy'; // set availability status of caller
}
break;
}
}
if (caller) {
// set availability status of callee
if (messageReceived.reply === "1") {
for (i = 0; connections.length; i++) {
if (messageReceived.id === connections[i].clientId) {
connections[i].status = 'busy';
break;
}
}
}
// sends the response to the corresponding caller
msg = {
type: "server-reply",
reply: messageReceived.reply,
calleeId: messageReceived.id,
answer: messageReceived.answer
}
caller.send(JSON.stringify(msg));
} else {
// sends the error message
msg = {
type: "error",
message: "Caller ID " + messageReceived.callerId + " doesn't exist."
}
ws.send(JSON.stringify(msg));
}
}
// receives the call close request from any client
if (messageReceived.type === 'close-call-client') {
var i;
var client = null;
// finds the other client
for (i = 0; i < connections.length; i++) {
if (messageReceived.clientId === connections[i].clientId) {
client = connections[i].webSocket;
connections[i].status = 'available'; // set the connection status to available
break;
}
}
// set available status for current client
for (i = 0; i < connections.length; i++) {
if (messageReceived.id === connections[i].clientId) {
connections[i].status = 'available';
break;
}
}
if (client) {
// forwards the message to the corresponding other client
msg = {
type: 'close-call-server',
clientId: messageReceived.id
};
client.send(JSON.stringify(msg));
} else {
// send error message
msg = {
type: "error",
message: "Callee ID " + messageReceived.calleeId + " doesn't exist."
}
ws.send(JSON.stringify(msg));
}
}
})
// on close event listnet
ws.on('close', () => {
// removing the corresponding client connection from array
var i;
for (i = 0; i < connections.length; i++) {
if (ws === connections[i].webSocket) {
log('Client with ID: ' + connections[i].clientId + ' disconnected.');
connections.splice(i, 1);
break;
}
}
})
})