0
If I want to be able to have multiple users and channels, do I need to have each user create a client in redis (or whatever the pub/sub used) to subscribe to the channel? And how would you get the messages? I am thinking this way, clients redis-pub/sub would need to be at the level where the websocket server is, because the client server communication would only be by websocket, I do not know what pub/sub uses for communication, but I am only wanting websocket between client and server, and redis(database + pub/sub) communicating locally within the server:
'use strict';
//CREATE WEB SERVER
var express = require('express');
var app = express();
var http = require('http').Server(app);
//CREATE WS
const WebSocket = require('ws');
const wss = new WebSocket.Server({ server: http, port: 8080 });
//CREATE REDIS
var redis = require('redis');
var redisClient = redis.createClient({host : 'localhost', port : 6379});
var clients = {};
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
// Aqui dependendo de certa mensagem recebida,
// como um login por exemplo, eu faria algo assim:
ws['user'] = obj.login.user.toString();
//CRIAR UM NOVO CLIENTE REDIS SUBS
clients[obj.login.user.toString()]['cliRedis'] = redis.createClient({host : 'localhost', port : 6379});
// SE INSCREVER NO CANAL
clients[obj.login.user.toString()]['cliRedis'].subscribe();
});
if("user" in ws) {
clients[ws.user]['cliRedis'].on("message", function(channel, message) {
console.log("Msg on subscriber: " + message);
//aqui enviaria os dados por websocket para o cliente
});
}
});
Up 1:
With the reply and comments of @rodorgas I was able to clarify a lot what I have to do. So I came to the conclusion that there are two possibilities, for the various customers to be able to listen to the messages sent by the pub/sub system:
1 - Using Centrifuge as indicated in the @rodorgas response:
2 - Using the pub/sub redis:
Comparisons:
Way 1 would have to have two active websockets connections, one for Centrifuge and one for Ws-server, at least I didn’t find anything in the Centrifuge documentation where I can handle messages that aren’t specific to the pub/sub, something like centrifuge-server.on("message", then I think it would even take two websockect connections in that mode. Then both would spend almost the same amount of sockets, because the sockets necessary for communication of pub/sub redis that would be won using the way 1, are lost having to open a new connection for communication with the client-Odot. The advantage of the way 1 is that it seems to be easier to understand, because the pub/sub client is even in the client, which does not even exist in fact, because Centrifugo only requires messages by websocket, there is no cli-Centrifugo as there is a cli-redis, the client-centrifuge is just the client-Godot sending messages via websocket. Already the way 2 clients-redis would be stored inside a javascript object in the nodejs script. Way 1 I will have to send messages in Centrifuge pattern that are big compared to what I can do by sending in Way 2.
Anyway, I’m wondering which way to start implementing, maybe I’ll do both and pick the one that’s faster. Anyway I’m running out of time in the next few days to start working on it, so I still have time to think about what to do.
Completion:
I chose to implement with the pub/sub redis, so I studied I would have more control over what I am doing. But I did not rule out Centrifugo, it will serve me very well if I come to implement a chat in the game, because it is very good for this task, with it I have like, for example, create private conversations between only two clients, among other facilities that are already implemented for you to use.
Do you want to distribute messages to people through the browser? I don’t know how the redis pubsub is going to help you with this, because it’s not a web technology. It would be useful if you wanted to distribute messages to native servers or applications. In what appears to be your case, only websocket is sufficient. And maybe you want to use the
socket.io
instead ofws
(as the socket.io implements several fallbacks).– rodorgas
I don’t think I could pass on what I want very well, the messages from the pub/sub would not go directly to the customer, there would arrive the message and by websocket would go to the client, I will even edit.
– PerduGames
What I want: to create channels that are "pieces of the map" and all the players that are in this piece will hear the messages from this channel, my doubt is if I’m doing right above, creating the clients and storing in the server script. It would be: client sends message by websocket to the server, the server saved in the database/cache, client enters a channel where will be listening to the messages, redis pub/sub sends message searched in the database/cache, and so is sent via websocket to the client.
– PerduGames
Under " client sends message by websocket", the client is the browser. Under "client enters a channel ..." the client is the server in Node-js. It’s confusing. But I guess that’s right.
– rodorgas
I’m sorry, it is. Yes in "client sends message by webscoket" he is the browser. And "client enters a channel" it is the redis client that is on the same server, within
var clients
, and that’s where it comes in doubt, I really have to create a redis client for each websocket client?– PerduGames
The two questions. 1 - Do I have to create a redis client for each websocket client? if yes, enter the question 2 - The way(
... clients[ws.user]['cliRedis'].on("message" ...
) as I am listening to the above messages is correct?– PerduGames
– rodorgas
i am already using redis as cache for information, the pub/sub would be for channels, it is necessary, if not would have to send update message of the position of everyone online on the server to everyone, which would be bad.
– PerduGames
I have the client-game(can call browser) that connects to the server, when this happens, is created a cli-redis for it, the client-game sends its position to the server by websocket, then the server saved in redis that information, cli-redis subscribes to a channel that is the area around it, so it only interests you information in that area, avoiding unnecessary information to be sent. Another client-game connects in the same area, creates another cli-redis for it, which will enter the same channel, so each gets the position of the other, synchronizing their positions in the game.
– PerduGames