面试官问项目亮点:直播弹幕设计

项目亮点第一期。。。。。。项目亮点第一期。。。。。。项目亮点第一期。。。。。。

大家好,我是南哥。

一个Java学习与进阶的领路人,跟着南哥我们一起Java成长。

文章目录

  1. 直播弹幕设计
    1. 底层数据结构支持
    2. 弹幕列表查询
    3. 系统流程
    4. 消息丢失问题

1. 直播弹幕设计

1.1 底层数据结构支持

南友们看看右下角的弹幕列表,这个弹幕列表就是我们今天要的攻克的对象,至于中间视频直播的走马灯弹幕,它其实也是根据弹幕列表的数据来进行滚动。

南哥观察了下这个直播间,现在有41.5万人在观看!

alt

计算机世界实际上是现实世界的抽象,那弹幕列表我们要用什么数据结构支持。

我希望用的是Redis,Redis官方写着这么霸气的宣传语。

Get the world’s fastest in-memory database from the ones who built it

从构建者那里获取世界上最快的内存数据库

而底层数据结构我们使用Redis五大基本数据类型之一:Zset。Zset是一种有序集合类型,它有一个score值,score值用来存储用户发送弹幕的时间戳,那整个列表就会根据时间戳来进行排序。

而Zset元素的值就作为用户弹幕,例如上图的:剧本演了又演

有了底层数据结构支持,我们来说说这个弹幕列表有什么功能限制。大家有没注意到我们进入直播间,直播间是不会把所有的弹幕内容都 显示出来的,往往只是显示前10条。

那我们也给弹幕列表加上这个特性,在Redis的Zset结构设置只保留前10条的属性。

// 创建Zset数据结构并设置10条的限制
public class DanmakuService {

    private Jedis jedis = new Jedis("localhost");

    public void addDanmaku(String roomId, String danmaku, long timestamp) {
        String key = "room:" + roomId + ":danmaku";
        jedis.zadd(key, timestamp, danmaku);
        // 只保留最新的10条弹幕
        jedis.zremrangeByRank(key, 0, -(11));
    }
}

1.2 弹幕列表查询

那用户进入直播间,弹幕列表是怎么查询出来的?

我们按最简单高效来,用户进入直播间,客户端调用API接口去查询出Redis里的弹幕列表。

有南友会问:这只是最近的前10条聊天记录,后面的呢?

别急,有两种方案。

(1)轮询查询

客户端轮询查询API接口,不断抓取出用户发出的新弹幕。具体细节的话,客户端第一次查询出的弹幕列表的数据结构是:[(时间戳1: 弹幕1), (时间戳2: 弹幕2)]

后续查询客户端继续轮询调用API接口,同时携带当前弹幕列表的最大时间戳入参。而后端服务就会根据该时间戳返回比该时间戳大的数据,用户发送的新的弹幕也就会显示出来。

// 轮询API接口
public class DanmakuService {

    private Jedis jedis = new Jedis("localhost");

    public Set<String> getRecentDanmaku(String roomId, long lastTimestamp) {
        String key = "room:" + roomId + ":danmaku";
        return jedis.zrangeByScore(key, lastTimestamp + 1, Long.MAX_VALUE);
    }
}

轮询API我们要设置多少时间轮询一次呢?我们先设置 3 秒轮询更新一次弹幕列表,后续再根据用户反馈、服务器资源进行优化调整。

(2)WebSocket技术

视频直播间有个特点,主播和观众是无时不刻在进行互动聊天的,这就要求音视频要实时同步了。那直播弹幕就

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Java面试突击 文章被收录于专栏

👉以面试官面试的形式,涵盖了你怒怼大厂面试官、拿下大厂面试所需掌握的核心知识、面试重点! 👉相信一定对你顺利通关面试、拿到理想Offer有所帮助! 👉花费大量精力去制作本专栏,创作不易,各位的支持就是我创作的最大动力!

全部评论

相关推荐

6 23 评论
分享
牛客网
牛客企业服务