使用WebSocket制作一个单机版弹幕系统非常简单,但是当单机性能达到瓶颈,需要扩展为集群部署时就会面临很多分布式问题,使用CONNMIX则无需担心这些问题,很少的代码即可完成一个高性能分布式WebSocket集群。
video:/v1/mesh/publish 接口往对应 video_id 发送实时弹幕,所有订阅该通道的ws客户端都将会收到消息。| 功能 | 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.yaml 配置文件的 options 选项,修改websocket的url路径
options:
- name: path
value: /barrage-videos
修改 entry.websocket.lua 的 on_message 方法如下:
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
接下来在现有系统的框架中实现主动弹幕推送
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}{"event":"@video","data":{"uid":1001,"video_id":100001,"msg":"Hello,World!"}}