系列文章目录
授权登录
一、实现Redis的订阅机制
引入Jedis 的Jar包
为什么要使用Jedis,而不是使用springboot的redis组件呢? 因为springboot的redis组件也依赖netty,容易引发Jar包冲突。
在pom.xml文件中加入:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.5.1</version>
</dependency>
创建订阅线程
/**
* @author Mr.Guo
* @date 2021/3/11 上午10:14
*/
public class RedisSubscriberThread implements Runnable {
private final String[] channel;
private static Thread thread;
private RedisSubscriberThread(String[] channel) {
this.channel = channel;
}
@Override
public void run() {
final RedisSubscriber subscriber = new RedisSubscriber();
Xa87RedisPool.getResource().subscribe(subscriber, channel);
}
public static void start(String... channel) {
thread = new Thread(new RedisSubscriberThread(channel));
thread.start();
Xa87RedisPool.getResource().sadd("xa87-im-sub-list", channel);
}
public static void stop(String channel) {
Xa87RedisPool.getResource().srem("xa87-im-sub-list", channel);
}
}
接收订阅消息
import cn.xa87.im.X;
import cn.xa87.im.packet.Xa87Packet;
import cn.xa87.im.packet.bean.SingleMsg;
import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.JedisPubSub;
/**
* @author Mr.Guo
* @date 2021/3/11 上午10:18
*/
@Slf4j
public class RedisSubscriber extends JedisPubSub {
@Override
public void onMessage(String topic, String message) {
log.info("Topic:" + topic + ",Message:" + message);
Xa87Packet packet = JSON.parseObject(message, Xa87Packet.class);
SingleMsg msg = JSON.parseObject(new String(packet.getBody()), SingleMsg.class);
String userId = msg.getToUser();
Channel channel = X.getChannelByUserId(userId);
if (null == channel) {
return;
}
channel.writeAndFlush(packet);
}
@Override
public void onPMessage(String pattern, String channel, String message) {
System.out.println("Pattern:" + pattern + ",Channel:" + channel + ",Message:" + message);
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println("onSubscribe---channel:" + channel + ",subscribedChannels:" + subscribedChannels);
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
System.out.println("onPUnsubscribe---pattern:" + pattern + ",subscribedChannels:" + subscribedChannels);
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
System.out.println("onPSubscribe---pattern:" + pattern + ",subscribedChannels:" + subscribedChannels);
}
}
发送订阅消息
import cn.xa87.im.packet.Xa87Packet;
import com.alibaba.fastjson.JSON;
/**
* @author Mr.Guo
* @date 2021/3/10 下午4:47
*/
public class MessagePublisher {
public static void pushMessage(String topic, Xa87Packet xa87Packet) {
Xa87RedisPool.getResource().publish(topic, JSON.toJSONString(xa87Packet));
}
}
二、测试效果
启动服务端
启动两个服务端,端口分别是18877、18878
启动使用python写的客户端
开始测试
分别登录用户a和用户b,之后用a给b发一个消息。