Listen to messages with multiple clients (pub / sub)

0

If I want to have multiple users and channels, do I need to create a client in redis (or whatever pub / sub used) to subscribe to the channel? and how would you get the messages? I'm thinking so, redis-pub / sub clients would need to be at the level where the websocket server is, since the client-server communication would only be by websocket, I do not know what pub / sub uses for communication, but I'm just 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 from @ 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 clients to hear the messages sent by the pub / sub system:

1 - Using the Centrifuge as indicated in @rodorgas' response:

2-Usingredispub/sub:

Comparisons:

Way1wouldwanttohavetwoactivewebsocketsconnections,oneforCentrifugalandoneforws-server,atleastIdidnotfindanythingintheCentrifugaldocumentationwhereIcanhandlemessagesthatarenotspecifictothepub/sub,somethinglikecentrifugal-server.on("menssage" ), so I think you would even need two websockect connections in that mode, so both would spend almost the same amount of sockets, redis pub / sub that would be gained using way 1, are lost having to open a new connection for communication with client-godot. The advantage of way 1 is that it seems to be easier to understand, since the pub / sub client is even in the client, that even does not really exist, because Centrifugus only requires messages via websocket, there is no cli-Centrifuge as there is a cli-redis, the client-centrifugo is just the client-godot sending messages via websocket. 2 way customers-pens would be stored in a javascript object in the script nodejs. Way 1 I'll have to send the Centrifugal pattern messages that are big compared to what I can do by sending in the way 2.

Anyway, I'm hesitant about which way to start implementing, maybe do both and choose whichever is faster. Anyway I do not have time in the next few days to start working on it, so I still have time to think about what to do.

  

Conclusion:

I chose to implement with redis pub / sub, so I studied I would have more control over what I'm doing. But I did not discard the Centrifuge, 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 can, for example, create private conversations between only two clients, among other facilities that already are implemented for you to use.

    
asked by anonymous 24.10.2017 / 05:04

1 answer

1

The Centrifugue is a pubsub server, it "creates channels" in the websocket (actually it's a layer abstraction, it takes care of unique users and lets you group them into channels). This without having redis as an intermediary.

So let's assume that your map is divided into sectors. The intent is to deliver a message to thousands of players who are in the sector (1.1) of the map. Put it like this in the browser:

<script type="text/javascript">

    var centrifuge = new Centrifuge({
        url: 'http://localhost:8000/connection',
        user: "USER ID",
        timestamp: "UNIX TIMESTAMP SECONDS",
        token: "SHA-256 HMAC TOKEN"
    });

    // inscreva o usuário no setor correspondente
    centrifuge.subscribe("(1,1)", function(message) {
        console.log(message);
    });

    centrifuge.connect();

</script>

In the backend, on the server side. Send a message like this (assuming backend on nodejs, but the centrifuge supports multiple languages):

Client = require("jscent");

var c = new Client({url: "http://localhost:8000", secret: "secret"});

c.publish("(1,1)", {"input": "test"}, function(err, resp){console.log(err, resp)});

When your game is huge and you have many servers, you put the redis on the parade. The Centrifuge uses the redis to do load balancing, for example, in high-scale situations.

Maybe someone comes up with an idea using redis in the middle. But I see that the redis will always stay in the middle: you will need to move to the browser later. Centrifuge really does it all in one go. I would use it.

    
25.10.2017 / 03:32