改造弹幕功能
文档对应视频课程中5.8、5.9、5.10章节,请小伙伴们对应学习。
如图,分为发送弹幕和随着时间点展示弹幕信息两部分
WebSocket
- PHP通过http轮询实现
- Go通过WebSocket方式实现
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
http轮询和websocket的区别,左边部分是http轮询模式,右边部分是websocket模式
websocket api
//判断浏览器是否支持websocket
if("WebSocket" in window){
//建立连接
var ws = new WebSocket('ws://127.0.0.1:8099/barrage/ws');
ws.onopen = function(event){
console.log(event);
console.log('连接了');
};
ws.onmessage = function(e) {
//循环获取播放器时间,根据时间读取对应的弹幕
wsSendDanmu(e.data)
};
ws.onclose = function(event){console.log("已经与服务器断开连接\r\n当前连接状态:"+this.readyState);};
ws.onerror = function(event){console.log("WebSocket异常!");};
} else {
console.log("您的浏览器不支持WebSocket");
}
Go websocket
使用 github.com/gorilla/websocket ```go //配置是否支持跨域 var ( upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } )
func (this BarrageController) BarrageWs() { var ( conn websocket.Conn err error data []byte barrages []models.BarrageData ) //建立连接 if conn, err = upgrader.Upgrade(this.Ctx.ResponseWriter, this.Ctx.Request, nil); err != nil { goto ERR } for { //获取客户端信息 if , data, err = conn.ReadMessage(); err != nil { goto ERR } var wsData WsData json.Unmarshal([]byte(data), &wsData) endTime := wsData.CurrentTime + 60 //获取弹幕数据 , barrages, err = models.BarrageList(wsData.EpisodesId, wsData.CurrentTime, endTime) if err == nil { //发送信息到客户端 if err := conn.WriteJSON(barrages); err != nil { goto ERR } } }
ERR: conn.Close() }
**发送弹幕功能**
接口地址:
>/barrage/save
接受参数和返回信息
1. 接收参数为:
uid(用户ID)
content(弹幕内容)
current_time(<font color=red>发送弹幕时播放的时间点</font>)
episodes_id(剧集ID)
video_id(视频ID)
2. 返回信息:
ret返回码 0=正确
3. 业务逻辑:
保存到barrage表中,current_time(发送弹幕时播放的时间点) <font color=red>最关键</font>
>player.getCurrentTime() 获取当前播放时间点
**获取弹幕功能websocket**
根据时间点获取对应的弹幕信息,用到一个关键的功能点:<font color=red>阿里云播放器支持获取视频播放到时间点的功能</font>。
```javascript
//播放器播放事件,开始通过websocket发送请求到服务端
player.on('play',function(e){
startSend();
});
//播放器暂停事件,暂停时清除弹幕的事件
player.on('pause',function(e){
$('#danmu').danmu('danmuPause');
clearInterval(currentTimeStatus);
clearInterval(wsSendDanmuStatus);
});
player.on('playing',function(e){
var playerStatus = player.getStatus();
if(playerStatus != 'play'){
startSend();
}
});
//开启弹幕和像服务端发送send
function startSend(){
$('#danmu').danmu('danmuResume');
wsSend();
//一分钟一次向websocket发送播放器时间,用来获取后面1分钟内的弹幕
clearInterval(currentTimeStatus);
currentTimeStatus = setInterval(function(){
wsSend();
},60000);
}
获取弹幕信息接口
接口地址:
/barrage/ws
接受参数和返回信息
接收参数为:
episodesId(剧集ID)
currentTime(视频播放时间点)返回信息:
id = 弹幕ID
content = 弹幕内容
currentTime = 发送弹幕时视频播放时间业务逻辑:
从barrage表中,获取status=1 episodes_id=接受参数以及从current_time开始1分钟内的数据信息,按照current_time正序SELECT id,content,`current_time` FROM barrage WHERE status=1 AND episodes_id=? AND `current_time`>=? AND `current_time`<? ORDER BY `current_time` ASC