最近一直在學swoole就老想着用它做點東西,之前有接觸過個一個jquery彈幕插件,於是我便使用這個插件結合swoole做了一個彈幕網站demo。
插件github地址:https://github.com/chiruom/jquery.danmu.js
使用教程:地址裏都有介紹,這裏就不一一贅述了
官方提供了一個demo,前端頁面我就直接在官方demo的基礎上加上了websocket,頁面效果展示如下:
前端index.html代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery.danmu.js jQuery彈幕插件</title>
<style>
body {
font-family: "Microsoft YaHei" ! important;
font-color:#222;
}
pre {
line-height: 2em;
font-family: "Microsoft YaHei" ! important;
}
h4 {
line-height: 2em;
}
#danmuarea {
position: relative;
background: #222;
width:800px;
height: 445px;
margin-left: auto;
margin-right: auto;
}
.center {
text-align: center;
}
.ctr {
font-size: 1em;
line-height: 2em;
}
</style>
<!--官方demo裏沒有jquery.min.js 這裏 用的是百度的CDN公共庫-->
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="../dist/jquery.danmu.min.js"></script>
</head>
<body class="center">
Demo<br><br>
<!--黑背景和彈幕區-->
<div id="danmuarea">
<div id="danmu" >
</div>
</div>
<!--控制區-->
<div class="ctr" >
<button type="button" onclick="resumer() ">彈幕開始/繼續</button>
<button type="button" onclick="pauser()">彈幕暫停</button>
顯示彈幕:<input type='checkbox' checked='checked' id='ishide' value='is' onchange='changehide()'>
彈幕透明度:
<input type="range" name="op" id="op" onchange="op()" value="100"> <br>
當前彈幕運行時間(秒):<span id="time"></span>
設置當前彈幕時間(秒): <input type="text" id="set_time" max=20 />
<button type="button" onclick="settime()">設置</button>
<br>
發彈幕:
<select name="color" id="color" >
<option value="white">白色</option>
<option value="red">紅色</option>
<option value="green">綠色</option>
<option value="blue">藍色</option>
<option value="yellow">黃色</option>
</select>
<select name="size" id="text_size" >
<option value="1">大文字</option>
<option value="0">小文字</option>
</select>
<select name="position" id="position" >
<option value="0">滾動</option>
<option value="1">頂端</option>
<option value="2">底端</option>
</select>
<input type="textarea" id="text" max=300 />
<button type="button" onclick="send()">發送</button>
</div>
<script>
var wsServer = 'ws://192.168.8.131:9502';
var websocket = new WebSocket(wsServer);
websocket.onopen = function(evt){
console.log('連接成功');
$("#danmu").danmu('danmuResume');
}
websocket.onmessage = function(evt){
console.log('接收數據:'+evt.data);
var new_obj=eval('('+evt.data+')');
console.log(new_obj);
$('#danmu').danmu("addDanmu",new_obj);
}
websocket.onclose = function(evt){
console.log("服務器拒絕");
}
websocket.onerror = function(evt,e){
console.log('錯誤:'+evt.data);
}
//初始化
$("#danmu").danmu({
left:0,
top:0,
height:"100%",
width:"100%",
speed:20000,
opacity:1,
font_size_small:16,
font_size_big:24,
top_botton_danmu_time:6000
});
//一個定時器,監視彈幕時間並更新到頁面上
function timedCount(){
$("#time").text($('#danmu').data("nowTime"));
t=setTimeout("timedCount()",50)
}
timedCount();
function starter(){
$('#danmu').danmu('danmuStart');
}
function pauser(){
$('#danmu').danmu('danmuPause');
}
function resumer(){
$('#danmu').danmu('danmuResume');
}
function stoper(){
$('#danmu').danmu('danmuStop');
}
function getime(){
alert($('#danmu').data("nowTime"));
}
function getpaused(){
alert($('#danmu').data("paused"));
}
//發送彈幕,使用了文檔README.md第7節中推薦的方法
function send(){
var text = document.getElementById('text').value;
var color = document.getElementById('color').value;
var position = document.getElementById('position').value;
var size =document.getElementById('text_size').value;
var time = $('#danmu').data("nowTime")+2;
var text_obj='{ "text":"'+text+'","color":"'+color+'","size":"'+size+'","position":"'+position+'","time":'+time;
websocket.send(text_obj);
document.getElementById('text').value='';
}
//調整透明度函數
function op(){
var op=document.getElementById('op').value;
$('#danmu').danmu("setOpacity",op/100);
}
//調隱藏 顯示
function changehide() {
var op = document.getElementById('op').value;
op = op / 100;
if (document.getElementById("ishide").checked) {
$("#danmu").danmu("setOpacity",1)
} else {
$("#danmu").danmu("setOpacity",0)
}
}
//設置彈幕時間
function settime(){
var t=document.getElementById("set_time").value;
t=parseInt(t)
$('#danmu').danmu("setTime",t);
}
</script>
</body>
</html>
服務端index.php代碼:
<?php
//服務器代碼
//創建websocket 服務器
$ws = new swoole_websocket_server("0.0.0.0",9502);
// open
$ws->on('open',function($ws,$request){
echo "新用戶 $request->fd 加入。\n";
$GLOBALS['fd'][$request->fd]['id'] = $request->fd;//設置用戶id
});
//message
$ws->on('message',function($ws,$request){
//發送每一個客戶端
//這裏也可以遍歷$ws->connections,遍歷的元素爲單個連接的fd
foreach($GLOBALS['fd'] as $i){
if ($request->fd == $i['id']) {
$ws->push($i['id'],$request->data.',"isnew":1}');
} else {
$ws->push($i['id'],$request->data.'}');
}
}
});
//close
$ws->on('close',function($ws,$request){
echo "客戶端{$request->fd} 斷開連接\n";
unset($GLOBALS['fd'][$request->fd]);//清除連接倉庫
});
$ws->start();
使用時服務端執行php index.php
然後瀏覽器訪問index.html即可
我這裏地址是 http://192.168.8.131/swoole-danmu/demo/index.html
當然上面的demo有一個問題,就是有新的用戶連接上或者刷新頁面的話,無法看到之前的彈幕,這一點就很容易解決了,把彈幕存儲起來就行了,官方也給瞭解決方案,就是在添加彈幕之前先使用ajax異步將彈幕存到數據庫中,每次刷新頁面或者有新用戶連接上打開頁面時先把數據庫裏的彈幕數據用ajax異步訪問服務端取出來並添加到頁面中。
這裏我就不做演示了,官方文檔以及demo裏都有詳細介紹