关于go:CONNMIX-开发-WebSocket-视频弹幕

8次阅读

共计 2272 个字符,预计需要花费 6 分钟才能阅读完成。

CONNMIX 开发 WebSocket 视频弹幕

应用 WebSocket 制作一个单机版弹幕零碎非常简单,然而当单机性能达到瓶颈,须要扩大为集群部署时就会面临很多分布式问题,应用 CONNMIX 则无需放心这些问题,很少的代码即可实现一个高性能分布式 WebSocket 集群。

要求

  • connmix >= v1.0.4

设计思路

  • 客户端在 ws 连贯胜利后,订阅一个视频 ID 的通道 video:<videoid>
  • 在发送弹幕的接口中,调用 connmix 任意节点的 /v1/mesh/publish 接口往对应 video_id 发送实时弹幕,所有订阅该通道的 ws 客户端都将会收到音讯。
  • 以上都是增量推送设计,全量通常都是在页面加载时通过一个全量 api 接口获取。

交互协定设计

  • 当用户发送 100001@video 咱们在 lua 代码中就执行订阅 video:100001 通道。
  • 前端切换视频时,可先发送勾销弹幕音讯,而后发送新的订阅弹幕音讯。
性能 json 格局
订阅弹幕 {“op”:”subscribe”,”channel”:”100001@video”}
勾销弹幕 {“op”:”unsubscribe”,”channel”:”100001@video”}
弹幕事件 {“event”:”@video”,”data”:{“uid”:1001,”video_id”:100001,”msg”:”Hello,World!”}}
胜利 {“result”:true}
谬误 {“code”:1,”msg”:”Error”}

装置引擎

  • CONNMIX https://connmix.com/docs/1.0/#/zh-cn/install-engine

批改配置

connmix.yaml 配置文件的 options 选项,批改 websocket 的 url 门路

options:
  - name: path
    value: /barrage-videos

CONNMIX 编码

批改 entry.websocket.luaon_message 办法如下:

  • 当承受到 subscribe、unsubscribe 音讯时,执行订阅 / 勾销订阅对应的通道
function on_message(msg)
    --print(msg)
    if msg["type"] ~= "text" then
        conn:close()
        return
    end

    local conn = mix.websocket()

    local data, err = mix.json_decode(msg["data"])
    if err then
        mix_log(mix_DEBUG, "json_decode error:" .. err)
        conn:close()
        return
    end

    local op = data["op"]
    local channel_raw = data["channel"]
    local channel_table = mix.str_split(channel_raw, "@")
    if table.getn(channel_table) ~= 2 then
        mix_log(mix_DEBUG, "invalid channel:" .. channel_raw)
        conn:close()
        return
    end
    local video_id = channel_table[1] --Lua 的 table 索引默认从 1 开始
    local channel_type = channel_table[2]
    
    if op == "subscribe" and channel_type == "video" then
        local err = conn:subscribe("video:" .. video_id)
        if err then
            mix_log(mix_DEBUG, "subscribe error:" .. err)
            conn:close()
            return
        end
    end
    
    if op == "unsubscribe" and channel_type == "video" then
        local err = conn:unsubscribe("video:" .. video_id)
        if err then
            mix_log(mix_DEBUG, "unsubscribe error:" .. err)
            conn:close()
            return
        end
    end

    conn:send('{"result":true}')
end

API 编码

接下来在现有零碎的框架中实现被动弹幕推送

  • 能够在 spring、laravel 框架中写一个发送弹幕接口
  • 该接口中验证完用户身份后,执行以下 http 申请实现推送
  • 如果发送申请十分频繁,能够改用 websocket-api 推送 晋升性能
curl --request POST 'http://127.0.0.1:6789/v1/mesh/publish' \
--header 'Content-Type: application/json' \
--data-raw '{"c":"video:100001","d":"{\"event\":\"@video\",\"data\":{\"uid\":1001,\"video_id\":100001,\"msg\":\"Hello,World!\"}}"}'

测试

应用 wstool 进行测试

  • 连贯 ws://127.0.0.1:6790/barrage-videos
  • 发送 {"op":"subscribe","channel":"100001@video"}
  • 接管到 {"result":true}
  • 执行 curl 被动推送
  • 接管到 {"event":"@video","data":{"uid":1001,"video_id":100001,"msg":"Hello,World!"}}
正文完
 0