使用Redis来实现在线人数的查看
在学习程序员老罗的easylive项目当中,遇到了一个对我现阶段来说很有意思的功能,那就是实现在线人数查看的功能,我第一次接触到这个功能是在学习WebServlet的监听器的时候.那时候是使用Listener监听器的Session事件和Context的生命周期来实现这个功能?具体的有点忘记了反正思路就是这样,在这个项目当中又遇到了这个功能.
业务实现环境
- Redis 7.4.0 重要()
- JAVA 8
- SpringBoot 2
1. 功能运用场景
因为easyLive项目是仿B站的一个项目,所以视频播放界面就会有一个显示几人正在观看的数据
2. 实现方法
- 使用netty
在视频里一开始提到可以使用websocket来查看有多少用户连接到服务器(websocket网络编程之前学过一点,但是并没有实战用过,所以只知道思路忘记了具体怎么操作) - 使用Redis缓存 (实现)
这里的思路是前端利用心跳机制,每隔一段事件发送心跳包来更新确认用户的状态,这里包含了用户的deviceId和VideoId
不选用netty是因为整个项目目前为止就这里使用了感觉没必要所以就不用了(其实我感觉私信方面也可以用,视频没看完,倒时候再观察)
3. 实现过程
接下来开始实现这个功能
1. 增加在线人数
首先在对应的控制器里新建一个控制器方法
这里返回的i就是在线人数了,进入这个方法
这里就是实现代码了
首先设置Redis里的key的k值,这里分为两个,一个是playOnlineCountKey,这里是视频文件当前的观看人数(因为B站不是算当前视频而是算视频文件的,这里存在分P)
userPlayOnlineKey则是记录当前视频文件下有几个用户在观看(就是通过这个key来检测用户是否有在看视频从而对上面的playOnlineCountKey来进行增减)
这里判断一下这个key是否存在,如果当前当前fileId下的deviceId这个key不存在的话则创建这个key并且设置过期时间为8s(K为deviceId,V为视频文件ID)
然后再给上面playOnlineCountKey的key值自增1,这里如果key不存在的话Redis会初始化一个K为fileID的key,然后V初始化为0,这里自增之后则是1,再使用intvalue()方法返回v值
如果存在则是将过期时间重置
之后返回playOnlineCountKey的值,这里如果发生阻塞之类的话可能会导致返回的时候这个key已经消失了这是Integer为null,而这个接口都是在观看视频的时候调用,所以当为null的时候直接返回1
2. 减少在线人数
当用户离开了视频的播放界面,此时前端就不会向后端发送带有当前fileId和deviceId的请求了,所以就不会更新队友的key,当key过期之后,就要减少当前视频的在线观看人数(因为还有其他用户在观看此视频,所以视频播放人数的key是当前视频完全没人观看的时候才消失)
要实现这个功能,那我们就要监听到key过期消失这个事件,我们新建一个类作为Redis的监听器Component
这个类集成了KeyExpirationEventMessageListener类
通过名字我们可以看出来,这个类就是监听key过期事件消息的一个监听器(感兴趣可以去了解一下Redis的事件机制)
这里先将redis的message类给转化为String
这里通过监听事件监听到message,消息体是过期key的名称也就是K值,此时将message转化为字符串类型,得到过期key的K值,通过比对在线人数业务的前缀来判断是否是实现减少在线数量的key.
当前缀满足要求时,将前缀去掉,取出fileId:deviceId的这个key
随后通过这个路径截取出fileId(fileId设计成了20个字符长度)
获取到fileId之后再减少指定fileId的playOnlineCountKey的值,自减1.
4.总结
使用Redis和心跳机制来实现了在线人数的变化查询,其实还有redis消息队列的,接下来会学到,之后再结合自己练习试试看使用kafka来代替消息队列.
标签:视频,在线,查看,Redis,key,人数,fileId From: https://www.cnblogs.com/MingHaiZ/p/18563822