为什么在 redis-cli 中使用了 subscribe 命令之后无法再执行 unsubscribe 等的命令

AUTHOR | nicechi
类别 | Redis
发表 | 2020-08-29 16:03:29
更新 | 2020-08-29 16:03:29

为什么在 redis-cli 中使用了 subscribe 命令之后便无法再执行 unsubscribe 等其他的命令? 

这是我一开始在 redis-cli 中学习 pubsub 命令的时候所遇到的最大的一个疑惑。

在 redis-cli 中输入 subscribe 命令之后,redis-cli 便进入了消息的订阅模式,再然后 redis-cli 就阻塞了整个进程,除非在输入了 Ctrl+C 之后才会退出订阅模式,并且同时也将会退出 redis-cli 客户端。就如下图所示:

订阅 nice channel

所以我就很疑惑,既然 redis-cli 在使用了 subscribe 之后就直接阻塞了进程,也无法再输入其他的命令。那么 unsubscribe 以及 punsubscribe 这两个命令的存在到底有什么样的意义呢?

下图是官方文档中对 subscribe 的介绍:

官方文档中对 subscribe 的介绍

这下我就更加迷惑了。文档里明明指出虽然在 client 中输入了 SUBSCRIBE 命令之后无法再去处理其他的命令,但还是可以去处理 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE、PING 以及 QUIT 这六种命令,但是在实际的使用过程中, redis-cli 明明就已经被阻塞了,谈何再去执行其他的指令呢?

原来,文档中所提到的 client 并不包括 redis-cli,而是指的是 Jedis、lettuce 这类的 redis 客户端。 也就是说只有 Jedis 以及 lettuce 这类的 redis 客户端才可以在运行了 subscribe 命令之后再去执行 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE、PING 以及 QUIT 这六种命令。

以下面的例子为例,使用 Jedis 来订阅指定的 channel :

//以 Jedis 为例
Jedis jedis=JedisPoolUtil.getJedis();
JedisPubSub pubSub=new JedisPubSub() {
	@Override
	public void onMessage(String channel, String message) {
		System.out.println("channel:"+channel+", message:"+message);
		//当收到的 message 值为 test 的时候,执行其他的命令
		if (message.equals("test")){
			
			//subscribe 期间只能执行如下的六种命令
			
			//jedis.quit();
			//this.subscribe();
			//this.punsubscribe();
			//this.unsubscribe();
			//this.psubscribe();
			//this.ping();
			
		}

	}
};
//监听 nice channel
jedis.subscribe(pubSub,"nice");

如果在使用 Jedis 来运行 subscribe 命令的期间再去运行除了那六个命令之外的其他命令的话,Jedis 将会报错:

redis.clients.jedis.exceptions.JedisDataException: ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context
	at redis.clients.jedis.Protocol.processError(Protocol.java:132) ~[jedis-3.1.0.jar:na]
	at redis.clients.jedis.Protocol.process(Protocol.java:166) ~[jedis-3.1.0.jar:na]
	at redis.clients.jedis.Protocol.read(Protocol.java:220) ~[jedis-3.1.0.jar:na]
	...

所以说,如果使用 redis-cli 来运行 subscribe 命令的话,将无法再去执行其他的任何命令,所以说 unsubscribe 对于 redis-cli 来说其实是没有什么实质上的意义。

 

 

 


CATEGORY

TOP