锦上添花的视频弹幕模块开发

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 锦上添花的视频弹幕模块开发
  • 非实时弹幕
  • image.png
  • 多节点实时弹幕
  • image.png
add: async (req) => {
    let { content, episodeId, playTime, productId } = req.body
    if (!(content && episodeId && Number(playTime) >= 0 && productId)) {
        return BackCode.buildError({ msg: '缺少必要参数' })
    }
    let token = req.headers.authorization.split(' ').pop()
    let userInfo = SecretTool.jwtVerify(token)
    let barrageItem = {
        episode_id: episodeId,
        product_id: productId,
        play_time: playTime,
        content: content,
        account_id: userInfo.id,
        head_img: userInfo.head_img,
        username: userInfo.username,
        del: 0,
    }
    await DB.BulletScreen.create(barrageItem)
    return BackCode.buildSuccess()
},

具体解释如下:

  1. let { content, episodeId, playTime, productId } = req.body;: 这行代码从请求的 body 中解构出弹幕的内容 (content)、集数 ID (episodeId)、播放时间 (playTime) 和产品 ID (productId)。这些参数都是客户端传来的。
  2. if (!(content && episodeId && Number(playTime) >= 0 && productId)) { return BackCode.buildError({ msg: '缺少必要参数' }) }: 这行代码用于判断是否缺少必要参数。如果其中任何一个参数为空或播放时间小于零,就会返回一个错误响应,提示缺少必要参数。
  3. let token = req.headers.authorization.split(' ').pop();: 这行代码从请求头中获取授权令牌 (authorization),然后将其拆分为两部分,取第二部分作为 token。
  4. let userInfo = SecretTool.jwtVerify(token);: 这行代码使用 SecretTool 工具类的 jwtVerify 方法对 token 进行解析,并返回包含用户信息的对象。
  5. let barrageItem = { ... }: 这是一个对象字面量,用于存储要添加到数据库的弹幕数据。其中包含集数 ID、产品 ID、播放时间、内容、账户 ID、头像、用户名和删除标志等信息。
  6. await DB.BulletScreen.create(barrageItem);: 这行代码使用模型 BulletScreencreate 方法创建一个新的弹幕实例,并将前面构建的 barrageItem 对象作为参数传递给它。通过这个操作,弹幕数据被写入到数据库中。
  7. return BackCode.buildSuccess();: 最后,返回一个成功的响应。

弹幕查询

list_by_episode: async (req) => {
  let { beginTime, endTime, episodeId, productId } = req.body
  if (!(productId && episodeId && Number(beginTime) >= 0 && endTime)) {
    return BackCode.buildError({ msg: '缺少必要参数' })
  }
  let barrageList = await DB.BulletScreen.findAll({
    where: { play_time: { [Op.between]: [beginTime, endTime] }, episode_id: episodeId, product_id: productId    }
  })
  return BackCode.buildSuccessAndData({ data: barrageList })
},

现阶段浏览器网页主要的请求方式

用户如何在浏览器上不作任何操作的情况下接收到服务器的消息?

定时短轮询

定时1-3秒请求服务器接口查询状态

场景:扫码登录、扫码支付等等

缺点:

1.虽然是用户无感知得从服务器获取消息,但是控制台上会有一堆的网络请求; 2.而且定时频繁地请求服务器接口,会消耗带宽,增加服务器的负担; 3.用户扫码后需要等待几秒时间,页面才能跳转,会有明显的卡顿;

长轮询

将http接口请求的超时时间设置大些(满足用户扫码所需的时间),如果超时就发起下一次请求

场景:百度云网盘app扫码登录等

特点:

1.用户扫码之后,在电脑端网页就秒跳转,用户不需要等待

以上两种方式称为服务器推送技术本质上还是客户端主动请求数据,只不过在用户无感知的情况下,也叫comet技术

为什么使用websocket?

像轮询的机制还是以客户端发起的请求,对于简单的扫码登录状态查询可以适用,但是遇到数据传输量大的场景就不行了,同时不能保证及时接受到消息,类似视频会议、网页游戏等业务场景,需要两端互相传输大量的数据,因此就需要使用websocket

  • 由来

现在使用最广泛的应用层协议HTTP1.1基于TCP协议,同一时间内客户端和服务端只能有一方主动发送数据,称为半双工

而TCP协议是全双工的,同一时间内两端都可以同时像对方发送数据,称为全双工

为了满足两端相互发送大量的场景,兴起了基于TCP协议的应用层协议websocket

 

  • 什么websocket?
  • 定义

是一种在单个TCP连接上进行全双工通信的协议使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据

在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

-   优点
    -   节省资源:对比客户端轮询请求后端接口,更加节省服务器资源和宽带
    -   更强实时性:由于协议是全双工的,所以服务器可以随时主动给客户端下发数据,延迟更小
    -   保持连接状态:HTTP请求建立一次链接就断开,而websocket是持久性链接
-   使用场景
    -   弹幕
    -   多玩家游戏
    -   视频会议
    -   股票基金报价实时更新
    -   体育实况更新
    -   音视频聊天
    -   在线教育
    -   社交订阅

弹幕获取-前端模块编码实战开发

自定义封装websocket

/**
 * 弹幕逻辑配置
 */
import { useRef, useState } from "react";
import { io } from "socket.io-client";
const useSocket = () => {
  // 弹幕实例变量名
  const socket = useRef<any>(null);
  // 发送的弹幕
  const videoDanmuList = useRef<any[]>([]);
  const initialize = () => {
    // 建立传输链接 http://127.0.0.1:8081
    socket.current = io("ws://127.0.0.1:8081");
    socket.current.on("connect", () => {
      console.log("socketio已连接");
    });
    onBulletChat();
  };
  // 发送弹幕事件
  const handleAddDanmu = (data: any) => {
    socket.current.emit("bulletChat", data);
  };
  // 监听bulletChat事件
  const onBulletChat = () => {
    socket.current.on("message", (data: any) => {
      videoDanmuList.current.push(data);
    });
  };
  return {
    videoDanmuList,
    initialize,
    handleAddDanmu,
    onBulletChat,
  };
};
export default useSocket;

后段启动websocket

app.js

const express = require('express');
const app = express();
const { createServer } = require('http');
const server = createServer(app)
server.listen(8081, () => {
  console.log('服务启动在:http://127.0.0.1:8081')
})

websocket.js

const { Server } = require('socket.io')
const Redis = require("ioredis");
// redis发布的api
const clientPublish = new Redis({ port: 6379, host: '8.130.120.189', password: 'xdclass.net' });
// redis订阅api
const clientSubscribe = new Redis({ port: 6379, host: '8.130.120.189', password: 'xdclass.net' });
clientSubscribe.subscribe('chat');
const websocket = (server) => {
    // 实例化socket
    const io = new Server(server, { cors: { origin: '*' } })
    // websocket建立链接
    io.on('connection', (socket) => {
        console.log('有客户端链接进来了')
        // 监听bulletChat事件
        socket.on('bulletChat', (info) => {
            clientPublish.publish('chat', JSON.stringify(info))
        })
    })
    // 订阅redis收到消息后,执行websocket的消息推送客户端
    clientSubscribe.on('message', (channel, message) => {
        io.emit('message', JSON.parse(message))
    })
}
module.exports = websocket

websocket使用模式

-   单播:点对点 私信私聊
-   多播:也叫组播(特定人群) 多人聊天,发布订阅
-   广播:游戏公告
如果你使用Node.js做服务端,那么该选择Socket.IO
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
图形学
unity实战之弹幕功能
使用unity也可以实现追剧弹幕效果
|
3天前
|
数据库
弹幕视频设计网站15--------------修复弹幕出现多次
弹幕视频设计网站15--------------修复弹幕出现多次
直播源码搭建技术弹幕消息功能的实现
今天我要分享的这个直播源码技术功能也是大家非常常见的,这个功能不仅仅应用在直播源码平台中,在各大影视app中也一直被应用,那这个功能是什么那?
直播源码搭建技术弹幕消息功能的实现
|
12月前
|
存储 缓存 运维
弹幕系统设计实践
弹幕系统设计实践
155 0
|
移动开发 前端开发 JavaScript
Web前端基础
Web前端基础
|
前端开发 关系型数据库 MySQL
EDG牛逼!我搞了一很骚的弹幕页面
EDG牛逼!我搞了一很骚的弹幕页面
166 0
EDG牛逼!我搞了一很骚的弹幕页面
|
JavaScript 前端开发 CDN
哇哦,弹幕居然是这么弄出来的,一文学会如何用js制作一个弹幕效果
哇哦,弹幕居然是这么弄出来的,一文学会如何用js制作一个弹幕效果
234 0
哇哦,弹幕居然是这么弄出来的,一文学会如何用js制作一个弹幕效果
|
算法 Android开发 计算机视觉
优酷移动端弹幕穿人架构设计与工程实战总结
优酷移动端弹幕穿人架构设计与工程实战总结
293 0
优酷移动端弹幕穿人架构设计与工程实战总结
|
前端开发
Web前端基础(11)
Web前端基础
128 0
Web前端基础(11)
|
前端开发
Web前端基础(14)
Web前端基础
117 0
Web前端基础(14)