| 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 | } |