久滴直播电商平台 · 技术博客系列 第 5 篇

🔖 标签:即时通讯 直播互动 腾讯云IM

前言

直播间里的弹幕互动是营造"氛围感"的关键——观众发弹幕、主播看到后回复、系统推送秒杀通知,这些消息都要在毫秒级别内送达和展示。如果弹幕延迟高、消息丢失、或者群管理混乱,直播体验会大打折扣。

久滴直播电商平台基于腾讯云 IM 的 AVChatRoom(音视频聊天室)模式,通过 SPI 抽象层 + REST API + 客户端 SDK 实现了完整的弹幕系统。本文将从服务端 IM 能力、营销联动、禁言管理、在线人数统计等维度,带你深入理解这套方案。

目录

  1. 直播 IM 的核心需求
  2. ImProviderSPI 接口全览
  3. TencentImProvider 实现要点
  4. 直播营销联动:秒杀/优惠券推送到群
  5. 在线人数的精确统计
  6. 禁言管理的业务场景

1. 直播 IM 的核心需求

直播场景对 IM 系统有几个特殊要求:

  • 低延迟:弹幕要在 100ms 内送达,否则主播看到的弹幕和观众发送的时间差太大
  • 高并发:热门直播间可能同时有上万人在发消息
  • 可控的群消息:主播/管理员需要禁言、踢人等管控能力
  • 系统通知:营销活动(秒杀开始、优惠券发放)要以系统消息的形式推送到弹幕流中

腾讯云 IM 的 AVChatRoom 模式天然满足这些需求——无人数上限、无需申请加入、支持服务端 API 管控。

2. ImProviderSPI 接口全览

久滴平台将 IM 能力抽象为 ImProviderSPI 接口,包含五大能力域:

public interface ImProviderSPI {

    // ===== 群组管理 =====
    String createLiveGroup(String liveName, String streamName,
                           String introduction, String notification);
    void destroyGroup(String streamName);
    List<ImGroupInfoVO> listAllGroups();
    ImGroupInfoVO getGroupInfo(String groupId);
    void modifyGroupInfo(String groupId, String introduction, String notification);

    // ===== 禁言管理 =====
    void forbidSendMsg(String groupId, List<String> userIds, long muteSeconds);
    List<ImMutedAccountVO> listMutedAccounts(String groupId);

    // ===== 在线人数 =====
    Long getOnlineMemberCount(String groupId);

    // ===== IM 账号管理 =====
    void registerUser(String userId, String nickName, String faceUrl);
    void deleteUser(String userId);

    // ===== 群消息 =====
    void sendGroupSystemMessage(String groupId, String content);

    String getProviderType();
}

设计亮点createLiveGroup 方法接收 streamName 作为 GroupId,实现了直播流与弹幕群的天然绑定——创建直播时自动创建对应的 IM 群,销毁直播时自动销毁群,无需额外的映射关系维护。

3. TencentImProvider 实现要点

腾讯云 IM 实现类通过 REST API 调用腾讯云服务。以创建群组为例:

@Service
@ConditionalOnProperty(name = "yudao.im.provider.type", havingValue = "tencent", matchIfMissing = true)
public class TencentImProvider implements ImProviderSPI {

    @Override
    public String createLiveGroup(String liveName, String streamName,
                                   String introduction, String notification) {
        JSONObject body = new JSONObject();
        body.put("Type", "AVChatRoom");      // 音视频聊天室类型
        body.put("Name", liveName);
        body.put("GroupId", streamName);     // GroupId = streamName
        body.put("Introduction", introduction);
        body.put("Notification", notification);
        body.put("MaxMemberCount", 10000);
        String resp = doPost(buildUrl(CREATE_GROUP_URL), body);
        return streamName;
    }
}

群成员信息增强

IM SDK 返回的群成员 ID 是原始的 account 字符串,但前端展示需要用户昵称和头像。久滴平台做了一层映射:

private void handlerMemberInfo(List<GetGroupMemberVO> groupMemberVOList) {
    Collection<Long> memberIds = new ArrayList<>();
    Collection<Long> adminIds = new ArrayList<>();
    String prefix = LiveTypeEnum.LIVING_IM_USER_PREFIX.getType() + "";

    for (GetGroupMemberVO vo : groupMemberVOList) {
        String account = vo.getMember_Account();
        if (account.startsWith(prefix)) {
            // 管理员账号带前缀,去掉前缀后查询 AdminUserApi
            adminIds.add(Long.parseLong(account.substring(prefix.length())));
        } else {
            memberIds.add(Long.parseLong(account));
        }
    }

    // 批量查询昵称和头像
    Map<Long, MemberUserRespDTO> memberMap = memberUserApi.getUserMap(memberIds);
    Map<Long, AdminUserRespDTO> adminMap = adminUserApi.getUserMap(adminIds);
    // ... 填充昵称头像到 VO 中
}

这里通过管理员/普通用户的前缀区分,分别从 AdminUserApiMemberUserApi 批量查询用户信息,避免了 N+1 查询问题。

4. 直播营销联动:秒杀/优惠券推送到群

这是直播 IM 最具商业价值的场景。当主播在管理后台触发秒杀活动时,系统会向直播间群发送系统通知,所有观众都能看到。

@Override
public void pushSeckillToLiveGroup(Long liveId, Long seckillActivityId) {
    // 1. 通过 liveId 找到对应的 streamName(即群 GroupId)
    String groupId = getGroupIdByLiveId(liveId);
    if (groupId == null) {
        log.warn("未找到直播间对应的群组 liveId={}", liveId);
        return;
    }

    // 2. 查询秒杀活动详情
    SeckillActivityRespApiDTO activity = seckillActivityApi.getSeckillActivity(seckillActivityId);

    // 3. 构造消息文本
    String content = String.format("【秒杀活动】%s 火热进行中!限时抢购,手慢无!",
        activity.getName());

    // 4. 通过 IM Provider 推送到群
    tencentService.sendGroupSystemMessage(groupId, content);
}

优惠券推送逻辑类似:

@Override
public void pushCouponToLiveGroup(Long liveId, Long couponTemplateId) {
    String groupId = getGroupIdByLiveId(liveId);
    CouponTemplateRespApiDTO template = couponApi.getCouponTemplate(couponTemplateId);
    String content = String.format("【优惠券福利】%s 已上线,快来领取吧!", template.getName());
    tencentService.sendGroupSystemMessage(groupId, content);
}

完整的调用链路:

管理后台 → POST /txlive/marketing/push-activity
  → LiveMarketingService.pushSeckillToLiveGroup()
    → ImProviderSPI.sendGroupSystemMessage(groupId, content)
      → 腾讯云 IM REST API
        → 客户端 MESSAGE_RECEIVED 事件
          → live-chat.vue 渲染系统通知(竖排"系统通知"样式)

5. 在线人数的精确统计

直播间右上角的"在线人数"是用户关注的重点之一。通过 getOnlineMemberCount 方法获取实时数据:

@Override
public Long getOnlineMemberCount(String groupId) {
    JSONObject body = new JSONObject();
    body.put("GroupId", groupId);
    String resp = doPost(buildUrl(GET_ONLINE_MEMBER_NUM_URL), body);
    // 解析响应,返回在线人数
    return parseOnlineCount(resp);
}

前端定时轮询这个接口(建议间隔 5-10 秒),展示在直播间 UI 上。使用轮询而非 WebSocket 推送,是因为在线人数的变化频率不需要毫秒级实时。

6. 禁言管理的业务场景

直播场景中,主播和管理员需要对违规用户进行禁言。久滴平台支持批量禁言和设置禁言时长:

// 接口签名
void forbidSendMsg(String groupId, List<String> userIds, long muteSeconds);

// 查询被禁言用户列表
List<ImMutedAccountVO> listMutedAccounts(String groupId);

典型业务场景:

  • 临时禁言:用户发了不当言论,禁言 10 分钟
  • 永久禁言:严重违规用户,禁言到直播结束
  • 解除禁言:管理员可以随时解除禁言
  • 禁言列表:管理后台展示当前被禁言的用户

管理后台提供了可视化的禁言管理界面,调用 POST /txlive/im/forbidSendMsg 接口即可操作。

总结

本文深入解析了久滴直播电商平台的 IM 弹幕系统:

  • ImProviderSPI 接口:五大能力域(群组管理/禁言/在线人数/账号管理/群消息),通过 SPI 解耦云厂商
  • streamName = GroupId:直播流与弹幕群的天然绑定,简化生命周期管理
  • 营销联动:秒杀/优惠券通过 sendGroupSystemMessage 推送到直播间弹幕流
  • 群成员信息增强:IM 返回的 account ID 映射到系统用户昵称和头像

下一篇我们将走进社区热度算法,看看时间衰减公式如何驱动圈子排行榜。


📦 久滴直播电商平台 是一个基于 Spring Boot 3 + Vue3 + UniApp 的全栈开源直播电商解决方案。

如果觉得本文对你有帮助,欢迎 点赞 ⭐ 支持!

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐