直播软件源码开发,直播间内消息系统的实现

本文介绍了如何使用HTTP短轮询和Redis的SortedSet数据结构快速搭建直播软件源码中的直播间消息系统。客户端定时轮询服务端获取消息,服务端利用Redis存储并按时间顺序处理消息,同时实现概率性过期消息删除,确保性能和存储效率。客户端则根据接收到的时间戳获取新消息。
摘要由CSDN通过智能技术生成

在直播软件源码开发过程中,消息系统是非常关键的,无论是直播间内的消息还是平台内的消息,都关系着用户的使用体验,所以今天我们先用一个简单的"拉"模型搭建一个简单的直播间消息系统。

基本实现思路:
直播软件源码客户端每隔一个极短的时间,例如1秒亦或者更短的时间,根据直播间的id来调用服务端的接口,轮询该直播间发生的消息,服务端这边我们使用redis的SortedSet的数据结构来存储消息,其中key是直播间的房间id,score是服务器接收到该消息事件生成的时间戳,value可以简单地直接存储该消息序列化后的字符串,这样可以按照时间顺序地去存储消息,并且配置过期消息的删除逻辑,整个消息的存储就可以简单地搭建起来。

消息存储用java的伪代码所示:

 long time = new Date().getTime();
 
try {
     // redis中插入消息数据
     jedisTemplate.zadd(V_UNIQUE_ROOM_ID, time, JSON.toJSONString(roomMessage));
 
     // 按照概率性的去删除redis中过期的消息数据
     if (probability()) {
           deleteOverTimeCache(V_UNIQUE_ROOM_ID);
        }
     } catch (Exception e) {
            log.error("message save error", e);
 }

可以看到直播软件源码消息存储,如果使用redis的sortedSet进行存储还是比较方便的,接下来我们需要处理就是redis中过期消息的删除,因为在直播软件源码中无效的过期消息是没有价值的(所有的消息可以做持久化存储),redis中如果单一的key存储的消息过多,也会导致消息的慢查,和内存的使用量不断增大,这是我们不想看到的,这边因为是示例代码,所以简单地处理一下删除逻辑。

    private void deleteOverTimeCache(String roomId) {
 
        Long totalCount = jedisTemplate.zcard(roomId);
 
        log.info("deleteOldTimeCache size is {}", totalCount);
 
        if (totalCount < 600) {
            return;
        }
 
        // 倒序删除过期数据
        Set<Tuple> tuples = jedisTemplate.zrangeWithScores(roomId, -601, -1);
 
        if (CollectionUtils.isNotEmpty(tuples)) {
            for (Tuple tuple : tuples) {
                // 这是第一个-600条的那个score
                double score = tuple.getScore();
                jedisTemplate.zremrangeByScore(roomId, 0d, score);
                break;
            }
        }
    }

上面的伪代码probability()首先先做一个概率性的判断,例如我们做百分之一的随机判断,判断该次请求是否要进行消息的删除(请注意我们删除的逻辑是放在插入的逻辑之中的。如果每一次插入都需要判断是否要删除过期数据,会影响插入的性能)。如果通过概率性判断后,我们就优先判断直播软件源码中某一直播间的消息个数,如果消息个数还是比较少的话,则退出删除逻辑,如果超过消息阀值,则按照时间倒序删除已经过期的消息。

说完了http短轮询消息的存储后,我们最后再简单地说一下客户端消息查询实现逻辑。直播软件源码客户端通过直播间id和时间戳两个字段来请求服务端以查询直播间消息,其中"时间戳"是每一次服务端返回的,这个时间戳是渐进式的,当下一次客户端来请求服务端的数据的时候,都会带来上次服务端返回的时间戳,伪代码如下:

   @Override
 public RoomMessage queryRoomMessages(MessageMessageReq messageMessageReq) {
 
        RoomMessage result = new RoomMessage();
 
        long timestamp = messageMessageReq.getTimestamp();
 
        Set<Tuple> tuples = null;
        if (timestamp == 0) {
            // 如果传递是0,说明这个客户端终端是第一次来轮询,我们只要返回一个最近最新的消息返回即可
            tuples = jedisTemplate.zrevrangeWithScores(UNIQUE_ROOM_ID, 0, 0);
        } else
            // 加上一毫秒,返回后续的消息,每次返回5个,防止客户端因为低端手机原因,过多的消息渲染不出来
            tuples = jedisTemplate.zrangeByScoreWithScores(UNIQUE_ROOM_ID, timestamp + 1, System.currentTimeMillis(), 0, 5);
        }
 
        List<EachRoomMessage> eachRoomMessages = new ArrayList<>();
        long lastTimestamp = 0L;
 
        if (!CollectionUtils.isEmpty(tuples)) {
            for (Tuple tuple : tuples) {
                //最后一次循环后,会把最后一条消息产生的时间戳,返回给客户端,这样下次客户端就可以拿着这个时间戳来进行查询
                lastTimestamp = new Double(tuple.getScore()).longValue();
                eachRoomMessages.add(JSON.parseObject(tuple.getElement(), EachRoomMessage.class));
            }
        }
 
        result.setTimestamp(lastTimestamp);
        result.setEachRoomMessages(eachRoomMessages);
        return result;
    }

上述三段比较完整地代码主要陈述了一个依赖http短轮询这种方式快速实现的直播软件源码直播间的能力,这种方式是比较粗糙的,不过却是一个很好的实现思路。以上就是“直播软件源码开发,直播间内消息系统的实现”的全部内容,希望对大家有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值