feat(backend): sync whiteboard info for readonly and non-readonly whiteboards

This commit is contained in:
Florent Chehab 2020-05-12 22:59:15 +02:00
parent b37c296542
commit 522d1b72a7
No known key found for this signature in database
GPG Key ID: 9A0CE018889EA246
3 changed files with 98 additions and 5 deletions

View File

@ -185,7 +185,7 @@ function startBackendServer(port) {
io.on("connection", function (socket) {
let whiteboardId = null;
socket.on("disconnect", function () {
WhiteboardInfoBackendService.disconnect(socket.id, whiteboardId);
WhiteboardInfoBackendService.leave(socket.id, whiteboardId);
socket.compress(false).broadcast.to(whiteboardId).emit("refreshUserBadges", null); //Removes old user Badges
});

View File

@ -1,4 +1,5 @@
const config = require("../config/config");
const ReadOnlyBackendService = require("./ReadOnlyBackendService");
/**
* Class to hold information related to a whiteboard
@ -103,11 +104,36 @@ class WhiteboardInfo {
}
}
/**
* Wrapper class around map to treat both the editable whiteboard and its read-only version the same
*/
class InfoByWhiteBoardMap extends Map {
get(wid) {
const readOnlyId = ReadOnlyBackendService.getReadOnlyId(wid);
return super.get(readOnlyId);
}
set(wid, val) {
const readOnlyId = ReadOnlyBackendService.getReadOnlyId(wid);
return super.set(readOnlyId, val);
}
has(wid) {
const readOnlyId = ReadOnlyBackendService.getReadOnlyId(wid);
return super.has(readOnlyId);
}
delete(wid) {
const readOnlyId = ReadOnlyBackendService.getReadOnlyId(wid);
return super.delete(readOnlyId);
}
}
class WhiteboardInfoBackendService {
/**
* @type {Map<string, WhiteboardInfo>}
*/
#infoByWhiteboard = new Map();
#infoByWhiteboard = new InfoByWhiteBoardMap();
/**
* Start the auto sending of information to all the whiteboards
@ -117,12 +143,21 @@ class WhiteboardInfoBackendService {
start(io) {
// auto clean infoByWhiteboard
setInterval(() => {
this.#infoByWhiteboard.forEach((info, whiteboardId) => {
this.#infoByWhiteboard.forEach((info, readOnlyWhiteboardId) => {
if (info.shouldSendInfo()) {
// broadcast to editable whiteboard
const wid = ReadOnlyBackendService.getIdFromReadOnlyId(readOnlyWhiteboardId);
io.sockets
.in(whiteboardId)
.in(wid)
.compress(false)
.emit("whiteboardInfoUpdate", info.asObject());
// also send to readonly whiteboard
io.sockets
.in(readOnlyWhiteboardId)
.compress(false)
.emit("whiteboardInfoUpdate", info.asObject());
info.infoWasSent();
}
});
@ -171,7 +206,7 @@ class WhiteboardInfoBackendService {
* @param {string} clientId
* @param {string} whiteboardId
*/
disconnect(clientId, whiteboardId) {
leave(clientId, whiteboardId) {
const infoByWhiteboard = this.#infoByWhiteboard;
if (infoByWhiteboard.has(whiteboardId)) {
@ -189,6 +224,20 @@ class WhiteboardInfoBackendService {
}
}
}
/**
* Get the number of clients on a whiteboard
*
* @param {string} wid
* @returns number|null
*/
getNbClientOnWhiteboard(wid) {
const infoByWhiteboard = this.#infoByWhiteboard;
const info = infoByWhiteboard.get(wid);
if (info) return info.nbConnectedUsers;
else return null;
}
}
module.exports = new WhiteboardInfoBackendService();

View File

@ -0,0 +1,44 @@
const ReadOnlyBackendService = require("./ReadOnlyBackendService");
const WhiteboardInfoBackendService = require("./WhiteboardInfoBackendService");
test("Clients lifetime same wid", () => {
const wid = "1";
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(null);
WhiteboardInfoBackendService.join("toto", wid, null);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(1);
WhiteboardInfoBackendService.join("tata", wid, null);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(2);
WhiteboardInfoBackendService.leave("tata", wid, null);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(1);
WhiteboardInfoBackendService.leave("toto", wid, null);
// no more user on whiteboard
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(null);
});
test("Clients lifetime both wid and readonly wid", () => {
const wid = "2";
const readOnlyWid = ReadOnlyBackendService.getReadOnlyId(wid);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(null);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(readOnlyWid)).toBe(null);
WhiteboardInfoBackendService.join("toto", wid, null);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(1);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(readOnlyWid)).toBe(1);
WhiteboardInfoBackendService.join("tata", readOnlyWid, null);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(2);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(readOnlyWid)).toBe(2);
WhiteboardInfoBackendService.leave("tata", readOnlyWid, null);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(1);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(readOnlyWid)).toBe(1);
WhiteboardInfoBackendService.leave("toto", wid, null);
// no more user on whiteboard
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(wid)).toBe(null);
expect(WhiteboardInfoBackendService.getNbClientOnWhiteboard(readOnlyWid)).toBe(null);
});