ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context
Asked Answered
C

2

32

I am using jdish.publish in my web app and jedis.subscribe in my desktop app. so both are separate app.

I have this pubsub class

public class RedisNewPostListener extends JedisPubSub {

    private final Jedis jedis;
    private final AppInstances appInstances;

    public RedisNewPostListener(AppInstances instances, Jedis jedis) {
        this.jedis = jedis;
        appInstances = instances;
    }

    @Override
    public void onMessage(String channel, String message) {
        String[] pos = message.split("##");
        double lat = Double.parseDouble(pos[0]);
        double lon = Double.parseDouble(pos[1]);

        List<GeoRadiusResponse> members = jedis.georadius("UsersByLocation", lon, lat, GEO_SEARCH_RANGE, GeoUnit.KM);

i am calling it like

RedisNewPostListener postListener = new RedisNewPostListener(instances, jedis);
jedis.subscribe(postListener, "NewPostArrived");

I am getting this error:

redis.clients.jedis.exceptions.JedisDataException: ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context
    at redis.clients.jedis.Protocol.processError(Protocol.java:117)
    at redis.clients.jedis.Protocol.process(Protocol.java:151)
    at redis.clients.jedis.Protocol.read(Protocol.java:205)
    at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)
    at redis.clients.jedis.Connection.getRawObjectMultiBulkReply(Connection.java:242)
    at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:248)
    at redis.clients.jedis.Jedis.georadius(Jedis.java:3452)
    at com.app.redis.RedisNewPostListener.onMessage(RedisNewPostListener.java:39)
    at redis.clients.jedis.JedisPubSub.process(JedisPubSub.java:129)
    at redis.clients.jedis.JedisPubSub.proceed(JedisPubSub.java:102)
    at redis.clients.jedis.Jedis.subscribe(Jedis.java:2628)
Cardialgia answered 1/8, 2016 at 18:44 Comment(3)
Are you sure you are not using same JedisPool to get Jedis in both W-App and D-App? If yes, you need to close the jedis-client.Scape
Once the client enters the subscribed state it is not supposed to issue any other commands, except for additional SUBSCRIBE, PSUBSCRIBE, UNSUBSCRIBE, PUNSUBSCRIBE, PING and QUIT commands.Caucasia
@КонстантинВан This is wierd since subscribed state is basically locking, so how is the client being reused? I am getting these errors after updating Jedis while it was working before. I see no way of how the connection is being returned to the pool while being in subscribe mode.Toper
P
62

It seems that you use the same jedis client for subscribe and publish. You just need to create another client and one is for subscribe and the other is for publish

Penny answered 29/7, 2018 at 23:35 Comment(3)
I tripped in the same error message when using the redis npm client for a web app in a slightly different context. I had made sure to have only one client for publish and another for subscribe, but I was calling redisClient.get() and redisClient.set() methods in some rarely used and forgotten route using the subscribing client. So if you also end up here from google make sure your subscribe client isn't doing work unrelated to exclusively listening/unsubscribing/quitting.Concertize
This answer is correct for Node.js Redis client as well.Spontoon
Absurdly this is correct. Could not find this in any documentation anywhere. Wow. thanksRevetment
T
1

In Redis, when a client subscribes to channels or patterns using commands like SUBSCRIBE or PSUBSCRIBE, the connection is put into a mode where only pub/sub commands (SUBSCRIBE, PSUBSCRIBE, UNSUBSCRIBE, PUNSUBSCRIBE, PING, QUIT, RESET) are allowed. Regular commands like SET cannot be executed until the client unsubscribes from all channels.

Tug answered 19/6 at 10:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.