Redis pub/sub limit - node.js

Using Redis pub/sub, is there a way to limit the number of listeners that Redis will publish to?
http://redis.io/commands/publish
For example, using Node.js parlance:
var redis = require('redis');
var rcPub = redis.createClient();
var rcSub = redis.createClient();
rcPub.publish('channel','messageA',{limit:1}); //desired functionality/syntax
basically, when I send messageA to Redis, I want to tell Redis to publish the message to only one listener/subscriber. Seems possible, but can Redis do this?
In the Redis docs, the command is:
PUBLISH channel message
what I am looking for is:
PUBLISH channel message limit
where limit is an integer. Seems reasonable, and easy to implement from Redis' perspective.

You can add a channel per subscribed, and then publish to a single user's channel when you need to communicate with him.

Related

Redis punsubscribe not unsubscribing

I have one redis client for pub-sub. I'm using a websocket message handler to dynamically subscribe to a redis channel. The payload of the websocket message contains an ID that I use to create the channel-name. So for example lobby:${lobbyID}:joined.
Subscribing to this channel works fine, messages are received when publishing to that channel.
But the issue that I'm having is that I want to unsubscribe from this channel at one point. My assumption by reading the redis-documentation is that I would use punsubscribe so I can unsubscribe from any channels with the pattern lobby:*:joined, but messages are still received after trying that.
import redis from 'redis';
const subClient = redis.createClient();
subClient.on('message', (channel, message) => {
// Received message x on channel y
});
const socketHandlerSubscribe = (lobbyID) => {
subClient.subscribe(`lobby:${lobbyID}:joined`);
}
const socketHandlerUnsubscribe = () => {
subClient.punsubscribe('lobby:*:joined'); // true
}
When using the redis-cli the pattern seems valid when using PUBSUB CHANNEL lobby:*:joined. I could solve this issue by passing a lobby ID to the unsubscribe handler aswell, but punsubscribe should be the solution for it.
I also encountered this earlier with a scenario where I looped through an array of user ID's and created a subscription for each on statuses:${userID} and tried a punsubscribe on statuses:*, without any success.
Am I doing something wrong or this is an issue node-redis related? I'm using redis version 2.8.0
I noticed that there are two different types of subscriptions. On channels and patterns. In my question I was subscribing to a channel, and unsubscribing on a pattern, these two are not 'compatible' so this won't work.
I used nc to debug this, as redis-cli won't allow additional commands when entering subscribed state.

Subscribe to multiple channels with ioredis

I have a broadcast server with socket.io and ioredis via node.
However, with my current form I can only subscribe to one channel a time.
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('mychannel');
Considering that I must have innumerable channels (one for each registered user, for instance) I cannot hard type every channel on the node server.
I've tried also redis.subscribe('*') but without success.
Any light?
Using redis.psubscribe('*') and redis.on('pmessage', handlerFunction) did the trick.

node.js, faye (bayeux) - after subscribe event

I have a chat server. And after the clients subscribes I want to look in a DB to see if there is any history for the chat room they subscribed to.
The problem is, that I can only catch "subscribe" events in extension which must do "return callback(message);" to return the message. If I do the history thingy here nothing gets publishes to the clients because client isn't actually subscribed.
Is there any way to know when client ready? Or some event that happens on successfull subscription?
Thanks!
You can attach a callback after creating the subscription that will fire when you are successfully subscribed and another when you fail to subscribe:
var http = require('http');
var faye = require('faye');
var faye_server = new faye.NodeAdapter({mount: '/faye', timeout: 120});
faye_server.listen(8089);
var subscription = faye_server.getClient().subscribe('/testing', function(message){console.log(message);});
subscription.callback(function(){console.log('Subscription successful and ready to use!');});
subscription.errback(function(){console.log('ERROR: Subscription failed!');});
This is documented on the faye mainpage although it's buried a bit. . . http://faye.jcoglan.com/browser/subscribing.html
This works on a node server, node client, or browser client as I've tested it.
Furthermore, what I have been doing to make sure my clients are up and running is this: create client, then try to subscribe to garbage channel name. Once that subscription comes up, fails, or times out (put 5 second time out around it) I take that as my client open success. It's a bit of a round about method, but it's working very well for me and faye makes it pretty clean by using callback and errback just like in my previous example.
Now that's all on the client side, but it gets much easier on the server side: http://faye.jcoglan.com/node/monitoring.html. Just use the extensions here and look for subscribe events from specific clients and you are good to go.
Hope that helps

How to subscribe to multiple channels on Redis NodeJS

I have a function which I will call from time to time.
function blah() {
sub.unsubscribe();
sub.subscribe("a");
sub.subscribe("b");
}
Above results in error message "Error: node_redis command queue state error."
Same as https://github.com/mranney/node_redis/issues/137
Once a connection is subscribed, it can only issue subscription related commands (subscribe, psubscribe, etc)
Might another part of your code be using the same connection?
You could also try and subscribe to multiple channels with one call sub.subscribe("a", "b") or subscribe to a pattern that matches your need?
I am currently using redis.I was also facing the same issue in which i was trying to subscribe a set of channels.
var redis = require('redis')
const subscribe = redis.createClient({
host: 'localhost',
port: 6379
})
subscribe.psubscribe(`user:chat:*`)
subscribe.on('pmessage', function(pattern, channel, message) {
console.log(channel, message, pattern)
// Write Your Awesome Code here.
})
Psubscribe used for subscribing for multiple channels using redis. You can subscribe multiple channel on the basis of pattern.

socketio and redisstore scaling efficiency

I am working on a pretty big project that involves sending data between clients. So, I am just researching on some new technologies out there. Anyways, thought I'd give Nodejs a try. I just have a question about socketio and redis.
When we are using the pub/sub functions in socketio, does every client connection create a new connection to redis? Or, does socketio use a max of create three connections (in total, regardless of the number of clients) to do the pub/sub stuff?
From the source, it seems that each client connection has two associated subscriptions to Redis (this.store in the code), but that each socket.io server has only three connections to Redis (source).
this.store.subscribe('message:' + data.id, function (packet) {
self.onClientMessage(data.id, packet);
});
this.store.subscribe('disconnect:' + data.id, function (reason) {
self.onClientDisconnect(data.id, reason);
});
Redis should be able to handle a lot of connections as well as subscriptions, but benchmarking is recommended as always.

Resources