不光redis能实现来聊天的功能,很多数据库都能实现,也不是说非得key-value类型的数据库,关系型数据库也可以,用心跳机制(多少时间访问数据库来维持数据的最新)
转载自https://www.cnblogs.com/qlqwjy/p/9784956.html
1,redis实现一对一的聊天功能(基于lpush和brpop实现)
一对一聊天的思路:(采用Lpush和Brpop实现)
1.消息生产者生产消息到redis中:生产消息的时候根据接收人的userName与消息的类型发送到对应的key,采用lpush发送消息(根据userName生成key)
2.消息的消费者根据userName,从userName的key中消费对应的消息。如果有必要可以将消息写到RDB中避免数据的丢失。(根据userName生成key的规则获取用户对应的消息)
3.消息的内容头部加入发送者,例如原来消息内容是:hello,为了知道消息的发送者可以改为:张三*-*hello(为了获取消息的发送者)
群聊功能(基于发布/订阅实现)
群聊的思路:采用发布订阅模式实现(publish和subscribe实现)
1.每个channel都有一个频道,每一个channel代表一个群,用户每次订阅这个房间都代表进入这个群,可以发送与接收消息
2.发送者每次发送消息都需要先进入房间,也就是订阅channel,之后可以向该频道发送消息
3.接收者需要先进入房间,也就是订阅channel,然后接收消息
也就是不管发送消息与接收消息,都需要先订阅channel进入房间。用户进入某个房间可以存入到zSet,每次进入某个房间和发送消息先判断是否已经进入某个房间。比如:
房间room1,则channel就是room1,保存其成员的set就是room1members。
总的来说:
每个房间都是一个channel,进入房间的成员订阅该channel。每个房间的成员保存在一个zset中,key可以定义为roomName+"users"
用户退出房间的时候需要退出该房间,也就是退订该channel,同时在zset中移除该成员。(退订只能调用JedisPubSub的unsubscribe实现)。
也就是一个房间对应的信息如下:
1一个channel,名称为 roomName 发送的群消息到这个channel
2一个zset,对应的key为roomName+“users”,保存的是进入该房间的用户,用户退出房间需要借助退出房间的消息以及退订实现
3发送群聊消息直接publish消息到该roomName即可。