From 533f2898871cc5c1a548308537fbcd4f8d4bbdf5 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 23 Apr 2021 11:44:58 -0300 Subject: identifier per socket connection --- socket.js | 60 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'socket.js') diff --git a/socket.js b/socket.js index 92a48bf..3db0f98 100644 --- a/socket.js +++ b/socket.js @@ -28,6 +28,7 @@ const originalSymbol = Symbol('Original item') const EventEmitter = require('events') const net = require('net') +const shortid = require('shortid') const { saveBackend, @@ -110,6 +111,8 @@ function validateCommand(command) { switch (command.code) { case 'initialize-backend': return typeof command.backend === 'object' + case 'set-socket-id': + return typeof command.socketId === 'string' } // No break here; servers can send commands which typically come from // clients too. @@ -243,7 +246,7 @@ function makeSocketServer() { // that's the responsibility of the caller (use server.listen()). const server = new net.Server() - const sockets = [] + const socketMap = Object.create(null) server.canonicalBackend = null @@ -252,13 +255,15 @@ function makeSocketServer() { const donePlaying = {} server.on('connection', socket => { - sockets.push(socket) + const socketId = shortid.generate() + + socketMap[socketId] = socket let nickname = DEFAULT_NICKNAME socket.on('close', () => { - if (sockets.includes(socket)) { - sockets.splice(sockets.indexOf(socket), 1) + if (socketId in socketMap) { + delete socketMap[socketId] } }) @@ -273,6 +278,7 @@ function makeSocketServer() { } command.sender = 'client' + command.senderSocketId = socketId command.senderNickname = nickname if (!validateCommand(command)) { @@ -286,25 +292,26 @@ function makeSocketServer() { switch (command.status) { case 'done-playing': { const doneSockets = donePlaying[command.queuePlayer] - if (doneSockets && !doneSockets.includes(socket)) { - doneSockets.push(socket) - if (doneSockets.length === sockets.length) { + if (doneSockets && !doneSockets.includes(socketId)) { + doneSockets.push(socketId) + if (doneSockets.length === Object.keys(socketMap).length) { // determine next track - for (const socket of sockets) { + for (const socket of Object.values(socketMap)) { // play next track } delete donePlaying[command.queuePlayer] } } + break } case 'ready-to-resume': { const readySockets = readyToResume[command.queuePlayer] - if (readySockets && !readySockets.includes(socket)) { - readySockets.push(socket) - if (readySockets.length === sockets.length) { + if (readySockets && !readySockets.includes(socketId)) { + readySockets.push(socketId) + if (readySockets.length === Object.keys(socketMap).length) { const QP = server.canonicalBackend.queuePlayers.find(QP => QP.id === command.queuePlayer) silenceEvents(QP, ['set-pause'], () => QP.setPause(false)) - for (const socket of sockets) { + for (const socket of Object.values(socketMap)) { socket.write(serializeCommandToData({ sender: 'server', code: 'set-pause', @@ -359,7 +366,7 @@ function makeSocketServer() { // Relay the command to client sockets besides the sender. - const otherSockets = sockets.filter(s => s !== socket) + const otherSockets = Object.values(socketMap).filter(s => s !== socket) for (const socket of otherSockets) { socket.write(serializeCommandToData(command) + '\n') @@ -374,6 +381,12 @@ function makeSocketServer() { } } + socket.write(serializeCommandToData({ + sender: 'server', + code: 'set-socket-id', + socketId + }) + '\n') + socket.write(serializeCommandToData({ sender: 'server', code: 'initialize-backend', @@ -392,6 +405,7 @@ function makeSocketClient() { const client = new EventEmitter() client.socket = new net.Socket() client.nickname = DEFAULT_NICKNAME + client.socketId = null // Will be received from server. client.sendCommand = function(command) { const data = serializeCommandToData(command) @@ -432,11 +446,16 @@ function attachBackendToSocketClient(backend, client, { // All actual logic for instances of the mtui backend interacting with each // other through commands lives here. - const partyGrouplike = {name: 'My Party Sources', isPartySources: true, items: []} + const partyGrouplike = { + name: `Party Sources - ${client.nickname}`, + isPartySources: true, + items: [] + } + + const partyGrouplikeMap = Object.create(null) backend.setAlwaysStartPaused(true) backend.setWaitWhenDonePlaying(true) - backend.loadPartyGrouplike(partyGrouplike) function logCommand(command) { const nickToMessage = nickname => `\x1b[32;1m${nickname}\x1b[0m` @@ -497,6 +516,8 @@ function attachBackendToSocketClient(backend, client, { actionmsg = `updated their nickname (from ${nickToMessage(command.oldNickname)})` senderNickname = command.nickname break + case 'set-socket-id': + return case 'set-pause': if (command.paused) { actionmsg = 'paused the player' @@ -548,6 +569,11 @@ function attachBackendToSocketClient(backend, client, { switch (command.sender) { case 'server': switch (command.code) { + case 'set-socket-id': + client.socketId = command.socketId + partyGrouplikeMap[command.socketId] = partyGrouplike + backend.loadPartyGrouplike(client.socketId, partyGrouplike) + return case 'initialize-backend': await restoreBackend(backend, command.backend) // TODO: does this need to be called here? @@ -559,7 +585,7 @@ function attachBackendToSocketClient(backend, client, { }) return } - // Again, no pause. Client commands can come from the server. + // Again, no break. Client commands can come from the server. case 'client': { let QP = ( command.queuePlayer && @@ -775,7 +801,7 @@ function attachBackendToSocketClient(backend, client, { if (partyGrouplike.items.every(x => x[originalSymbol] !== origItem)) { partyGrouplike.items.push(newItem) - backend.partyGrouplikeUpdated(partyGrouplike) + backend.partyGrouplikeUpdated(client.socketId, partyGrouplike) } }) } -- cgit 1.3.0-6-gf8a5