前言

  在学习T-io框架,从写一个Redis客户端开始一文中,已经简单介绍了Redis客户端的实现思路,并且基础架构已经搭建完成,只不过支持的命令不全,不过后期在加命令就会很简单了。本篇就要实现Publish/Subscribe功能。

Pub/Sub

  发布订阅模式在很多场景中用的都很频繁,这里不再赘述。下面看一下Redis中的命令。参考资料:https://redis.io/topics/pubsub

//发布
PUBLISH
//订阅
SUBSCRIBE
//模式匹配订阅
PSUBSCRIBE
//取消订阅
UNSUBSCRIBE
//取消订阅(模式匹配)
PUNSUBSCRIBE
//其他

PUBLISH/SUBSCRIBE

  命令使用方式很简单:

PUBLISH CHANNEL MESSAGE

例如:publish user helloworld

Client类中增加代码:

    @Override
public void publish(final String channel, final String message) {
sendCommand(Command.PUBLISH, channel, message);
} @Override
public void subscribe(final String... channels) {
sendCommand(SUBSCRIBE, channels);
}

调试代码如下:

 //发布
Tedis tedisPublish = new Tedis("192.168.1.225", 6379);
tedisPublish.publish("channel1","hello world");
 //订阅
Tedis tedis = new Tedis("192.168.1.225", 6379);
tedis.subscribe(new MyPubSub(),"channel1");

先订阅,后发布,订阅响应结果:

*3
$9
subscribe
$8
channel1
:1

通过响应结果可以看出,我们当前的命令是 subscribe,然后订阅的是channel1,当前共订阅了:1个。

发布响应结果:

:1

总共发给了:1个订阅客户端。这个结果就是订阅客户端的个数。

PSUBSCRIBE

命令格式如下:

PSUBSCIRBE  news.*

修改一下调试代码:

订阅

  tedis.pSubscribe(new MyPubSub(),"news.*");

响应结果:

*3
$10
psubscribe
$6
news.*
:1

发布

  tedisPublish.publish("news.sports","welcome to NBA");
tedisPublish.publish("news.country","this is china news");

订阅客户端收到消息:

*4
$8
pmessage
$6
news.*
$11
news.sports
$14
welcome to NBA *4
$8
pmessage
$6
news.*
$12
news.country
$18
this is china news

从响应结果可以看出,客户端订阅了 news.*,然后收到了news.sports,news.country的消息。

响应消息解析

  上述代码中有一个MyPubSub对象,它继承自抽象类TedisPubSub.这个类做了发布订阅核心的业务处理。通过对服务端返回的消息格式,我们可以发现,它的消息格式是统一的。

    EVENT_NAME --事件

    CHANNEL_NAME --频道

    OTHER --其他信息,根据每个事件可能不同

所以我们在做发布订阅的响应消息解析时,可以返回 List。这里以SUBSCRIBE/PSUBSCRIBE举例

 private boolean handleSubscribe(byte[] resp,List<Object> reply){
//是否普通订阅
boolean isSubscribe = Arrays.equals(SUBSCRIBE.raw, resp);
//是否模式匹配订阅
boolean isPSubscribe = Arrays.equals(Keyword.PSUBSCRIBE.raw, resp); if (isSubscribe || isPSubscribe) {
resetSubscribedChannels(reply);
//第二个值为 channel 名称
final byte[] channelBytes = (byte[]) reply.get(1);
//转化为 string
final String channel = getString(channelBytes); //调用事件 (onSubscribe,onPSubscribe 子类可以重写)
if (isSubscribe) {
onSubscribe(channel);
} else {
onPSubscribe(channel);
}
return true;
}
return false;
}
    public abstract void onSubscribe(final String channel);
public abstract void onPSubscribe(final String channelPatterns);

MyPubSub中重写上述两个方法。

    @Override
public void onSubscribe(String channel) {
System.out.println("订阅了:"+channel);
} @Override
public void onPSubscribe(String channelPatterns) {
System.out.println("订阅了:"+channelPatterns);
}

这样,我们就能够收到回调消息了。

订阅了:news.*

接收到消息同理:

   @Override
public void onMessage(String channel, String message) {
System.out.println(channel + " 收到了消息:"+message);
}
channel1 收到了消息:welcome to NBA.

  不过这里需要注意的一点是,在普通订阅的消息中只有【MESSAGE,CHANNEL,CONTENT】三个值,而模式匹配的订阅消息中,有【PMESSAGE,PATTERN,CHANNEL,CONTENT】四个值,其中就多了一个 PATTERN,也就是上文中的news.*,所以稍微做一下区分就可以了

 private boolean handleMessage(byte[] resp, List<Object> reply) {
boolean isMessage = Arrays.equals(MESSAGE.raw, resp);
boolean isPMessage = Arrays.equals(PMESSAGE.raw, resp);
if (isMessage || isPMessage) {
final byte[] secondBytes = (byte[]) reply.get(1);
final byte[] thirdBytes = (byte[]) reply.get(2);
final String second = getString(secondBytes);
final String third = getString(thirdBytes);
if (isMessage) {
onMessage(second, third);
} else {
final byte[] messageBytes = (byte[]) reply.get(3);
final String message = getString(messageBytes);
onPMessage(second, third, message);
}
return true;
}

调用示例

news.country(news.*)收到了消息:this is china news

总结

  本文简单的对RedisPub/Sub模式做了介绍,并且在客户端中做了相应的处理。当然其中也是大量参考了Jedis源码。本文就到这里啦,88

源码链接

Redis的Pub/Sub客户端实现的更多相关文章

  1. 【转】 使用Redis的Pub/Sub来实现类似于JMS的消息持久化

    http://blog.csdn.net/canot/article/details/52040415 关于个人对Redis提供的Pub/Sub机制的认识在上一篇博客中涉及到了,也提到了关于如何避免R ...

  2. Redis的Pub/Sub机制存在的问题以及解决方案

    Redis的Pub/Sub机制使用非常简单的方式实现了观察者模式,但是在使用过程中我们发现,它仅仅是实现了发布订阅机制,但是很多的场景没有考虑到.例如一下的几种场景: 1.数据可靠性无法保证 一个re ...

  3. Redis实战——Redis的pub/Sub(订阅与发布)在java中的实现

    借鉴:https://blog.csdn.net/canot/article/details/51938955 1.什么是pub/sub Pub/Sub功能(means Publish, Subscr ...

  4. 带你100% 地了解 Redis 6.0 的客户端缓存

    近日 Redis 6.0.0 GA 版本发布,这是 Redis 历史上最大的一次版本更新,包括了客户端缓存 (Client side caching).ACL.Threaded I/O 和 Redis ...

  5. redis的Pub/Sub

    redis的Pub/Sub机制类似于广播架构,Subscriber相当于收音机,可以收听多个channel(频道),Publisher(电台)可以在channel中发布信息. 命令介绍 PUBLISH ...

  6. Redis系列(三)-Redis发布订阅及客户端编程

    阅读目录 发布订阅模型 Redis中的发布订阅 客户端编程示例 0.3版本Hredis 发布订阅模型 在应用级其作用是为了减少依赖关系,通常也叫观察者模式.主要是把耦合点单独抽离出来作为第三方,隔离易 ...

  7. redis的pub/sub命令

    Redis 发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 下图展示了频道 cha ...

  8. redis的Pub/Sub功能

    Pub/Sub功能(即Publish,Subscribe)意思是发布及订阅功能.简单的理解就像我们订阅blog一样,不同的是,这里的客户端与server端采用长连接建立推送机制,一个客户端发布消息,可 ...

  9. Redis常用操作及客户端工具

    修改redis密码 打开redis.windows.conf,找到requirepass  设置密码重启服务即可 将redis安装为windows服务,批处理如下: redis-server.exe ...

随机推荐

  1. git相关的简单命令

    初次使用建议看这个ppt:http://www.bootcss.com/p/git-guide/    从现有仓库克隆 这需要用到 git clone 命令.如果你熟悉其他的 VCS 比如 Subve ...

  2. Windows应用程序对键盘与鼠标的响应

      编写程序: 设计一个窗口, 当单击鼠标左键时, 窗口中显示"LEFT BUTTON"; 当单击鼠标右键时, 窗口中显示"RIGHT BUTTON"; 当单击 ...

  3. c#中表达式的返回值是啥?

    今天在学javascript的时候发现它其中有一个语法是这样的(a="haha).length;这样也能够输出haha这个字符串的长度,然而我在使用c#的时候分行读取txt文本的时候也用这个 ...

  4. axios上传图片(及vue上传图片到七牛))

    浏览器上传图片到服务端,我用过两种方法: 1.本地图片转换成base64,然后通过普通的post请求发送到服务端. 操作简单,适合小图,以及如果想兼容低版本的ie没办法用此方法 2.通过form表单提 ...

  5. 什么是URI,URL以及URN,你真的理解了吗。

    先举一个例子,让大家对这三个名词又一个基本的概念: 1⃣️ ftp://ftp.is.co.za/rfc/rfc1808.txt 2⃣️ http://www.cnblogs.com/nods/p/8 ...

  6. 让input光标一直在最右边

    有时候,我们需要使的input输入框的在点击时光标一直居右边 例如:移动端,用手指去点击输入框,在输入框较小,手指又比较大,那么经常会在点击后,光标会在已有文字时,居左 我们的输入框文字肯定要居中的需 ...

  7. Android 进程回收

    1.Android 进程回收策略 众所周知,Android是基于Linux系统的.在Android进程回收策略中,Android进程与Linux进程根据OOM_ADJ阈值进行区分: OOM_ADJ & ...

  8. maven 项目目录图与web 应用结构图对比

    web应用结构图 -war | | | |++++META-INF | | |----WEB-INF | | |-classes | | |com/baidu/controller/Controlle ...

  9. 读书笔记week1——涂涵越

    这次读书笔记主要是就<程序员修炼之道>这本书的前半部分做一些总结以及发表一些自己的看法. 本书前面的一部分主要是一些程序员应该在工作中时刻注意的事情,一些关键的信息如下: 1.处理问题的态 ...

  10. 创建完美SDK的10个技巧

    [编者按]本文作者为 Gal Lavinsky,文中将列出10个零基础小技巧,帮你创建完美的Java SDK.文章系国内 ITOM 管理平台 OneAPM 编译呈现.以下为正文. 本文起源于笔者朋友的 ...