Question about Websocket's FrameworkController
Closed this issue · 4 comments
I've planned to use websocket for a real time communication between clients and an RESTful API built with Total. In this scenario there could be many clients let's say 1/10/100k. The websocket should be a message exchange between two or a limited group of clients.
Of course any client connected has to be stored in memory, more users means more RAM, but in this use case I think that the current implementation of send
and send2
functions could be improved.
I've look at Total source code here index.js@15332 and here index.js@15384
If I want to use id
parameter to sand a message just to one or limited number of clients the functions performs a for-loop against every clients and skip who is in the id
array or in blacklist
. That's fine for broadcast with blacklist, but not in the other case. Because I know exactly which of my client has to receive the message, why loop everything?
I mean, because I know the client.id
I can pick it directly in O(1)
complexity from self.connections
instead of actual O(n)
.
This is a little draft:
var clientIdMap = {};
function socket_live_notification() {
var self = this;
console.log("socket opened");
self.on('open', function(client) {
clientIdMap[client.user.id] = client.id;
});
self.on('close', function(client) {
delete clientIdMap[client.user.id];
sendTo(self, 32, {message : 'Quit: ' + client.user.id})
});
self.on('message', function(client, message) {
console.log(message)
});
}
function sendTo(self, id, payload) {
var client = self.connections[clientIdMap[id]]
client.send(payload)
}
In this example the idea is to map the user.id
(object from AUTH
) to the original client.id
, generated by Total. In this way if the client A knows the id of the client B, they can communicate directly and server should have a significant reduction of the CPU load in case we have many clients that sands many messages.
Please let me know what do you think about and forgive me if I have made some mistakes
It's OK.
.send()
is old very old method and it exists for backward compatibility (I want to replace it in Total.js v4)- your solution is OK
Hi
I've found a very similar issue in schedules management here index.js@1907, as I understand all schedules are managed with an array so clearing a task could be inefficient because framework has to loop the whole array to find the right one.
I think that using an approach similar for the websockets could speed up a lot this aspect of the framework. However, this time it's a bit more difficult to fix this behavior outside framework because F.schedules
is not an Object
.
I hope you'll appreciate this comments and don't bother you too much 😃
Hi, not a problem. You can cache the function in SCHEDULER
like this:
FUNC.myscheduleroperation = function() {
// do something
};
SCHEDULE(...., FUNC.myscheduleroperation);
And you can call it everywhere:
FUNC.myscheduleroperation();
Well yes, and what about clear the task?
I'll explain better the use case: Client A and B communicate with messages on socket. If Client A sends a particular message, Client B has to reply in 1h, if don't the server should automatically execute an action against Client A.
So, when Client A sends its message the server setup a schedule, when Client B reply this schedule has to be removed.
Currently the function SCHEDULE
return just the schedule uuid and not the index of its position in F.schedules
array, so the only way to remove the task, before it is executed, is to use F.clearSchedule(id)
. This function internally loop the array with F.schedules.remove('id', id);
.
So I mean that if F.schedules
would be an object like F.connections
it would be much more easier to remove a schedule from queue with just delete F.schedules[id]
.