Better README
[qomet.git] / sockets.js
1 var message = require("./public/javascripts/utils/socketMessages.js");
2 const params = require("./config/parameters");
3
4 // TODO: when teacher connect on monitor, io.of("appropriate namespace").on(connect student) { ... }
5 // --> 2 sockets on monitoring page: one with ns "/" et one dedicated to the exam, triggered after the first
6 // --> The monitoring page should not be closed during exam (otherwise monitors won't receive any more data)
7
8 function quizzRoom(socket) {
9 let students = { };
10
11 // Student or monitor stuff
12 const isTeacher = !!socket.handshake.query.secret && socket.handshake.query.secret == params.secret;
13
14 if (isTeacher)
15 {
16 // TODO: on student disconnect, too
17 socket.on(message.newAnswer, m => { //got answer from student
18 socket.emit(message.newAnswer, m);
19 });
20 socket.on(message.socketFeedback, m => { //send feedback to student (answers)
21 if (!!students[m.number])
22 socket.broadcast.to(students[m.number]).emit(message.newFeedback, { feedback:m.feedback });
23 });
24 socket.on("disconnect", m => {
25 // Reset student array if no more active teacher connections (TODO: condition)
26 students = { };
27 });
28 }
29
30 else //student
31 {
32 const number = socket.handshake.query.number;
33 const password = socket.handshake.query.password;
34 // Prevent socket connection (just ignore) if student already connected
35 if (!!students[number] && students[number].password != password)
36 return;
37 students[number] = {
38 sid: socket.id,
39 password: password,
40 };
41 socket.on(message.newFeedback, () => { //got feedback from teacher
42 socket.emit(message.newFeedback, m);
43 });
44 // NOTE: nothing on disconnect --> teacher disconnect trigger students cleaning
45 }
46 }
47
48 module.exports = function(io) {
49
50 // NOTE: if prof connected with 2 tabs and close 1, quizz should not break, thus following counter
51 let namespaces = { };
52
53 io.of("/").on("connection", socketProf => {
54 function closeQuizz(fullPath) {
55 namespaces[fullPath].counter--;
56 if (namespaces[fullPath].counter == 0)
57 {
58 // https://stackoverflow.com/questions/26400595/socket-io-how-do-i-remove-a-namespace
59 const connectedSockets = Object.keys(namespaces[fullPath].nsp.connected);
60 connectedSockets.forEach( sid => {
61 namespaces[fullPath].nsp.connected[sid].disconnect();
62 });
63 namespaces[fullPath].nsp.removeAllListeners();
64 delete io.nsps[fullPath];
65 }
66 }
67 // Only prof account can connect default namespace
68 socketProf.on(message.startQuizz, m => {
69 // m contient quizz ID + fullPath (initials+path+name)
70 const quizzNamespace = io.of(m.fullPath);
71 if (!namespaces[m.fullPath])
72 {
73 namespaces[m.fullPath] = { nsp:quizzNamespace, counter:1 };
74 quizzNamespace.on("connection", quizzRoom); //après ça : prof can connect in quizz too
75 socketProf.emit(message.quizzReady);
76 socketProf.on(message.endQuizz, m2 => {
77 closeQuizz(m.fullPath);
78 });
79 socketProf.on("disconnect", m2 => {
80 closeQuizz(m.fullPath); //TODO: this should delete all students in array
81 });
82 }
83 else
84 namespaces[m.fullPath]++;
85 });
86 });
87 }