1.后端利用php 安装swoole 不会的自行百度 不再赘述
创建 websocket.php文件
on('open', function ($ws, $request) {
//var_dump($request->fd, $request->get, $request->server);
//相当于记录一个日志吧,有连接时间和连接ip
// $roomId = $request->get['roomid'];
echo $request->fd.'-----time:'.date("Y-m-d H:i:s",$request->server['request_time']).'--IP--'.$request->server['remote_addr'].'-----';
// $ws->push($request->fd, $roomId);
});
//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
//记录收到的消息,可以写到日志文件中
echo "Message: {$frame->data}\n";
//遍历所有连接,循环广播
foreach($ws->connections as $fd){
//如果是某个客户端,自己发的则加上isnew属性,否则不加
if($frame->fd == $fd){
$ws->push($frame->fd, $frame->data.',"isnew":""');
}else{
$ws->push($fd, "{$frame->data}");
}
}
});
//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
echo "client-{$fd} is closed\n";
});
$ws->start();
直接执行 php websocket.php 运行后端websocket服务
2.前端利用 github大神写的 danmu.js 地址为:https://github.com/chiruom/jquery.danmu.js 内有文档 demo 可以自行研究需要的功能
//WebSocket
var room = GetRequest(); //房间号
var wsServer = 'ws://192.168.18.15:9505?roomid=' + room.roomid;
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
/*websocket.send("gaga");*/
//连上之后就打开弹幕
$('#danmu').danmu('danmuResume');
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
var time = $('#danmu').data("nowTime") + 1;
var text_obj = evt.data + ',"time":' + time + '}';//获取加上当前时间
// console.log(text_obj);
var new_obj = eval('(' + text_obj + ')');
// console.log(new_obj.roomid);
// 判断房间号是否一致展示在该房间
if (new_obj.roomid === room.roomid) {
$('#danmu').danmu("addDanmu", new_obj);//添加弹幕
}
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
//初始化
$("#danmu").danmu({
left: 0,
top: 0,
height: "100%",
width: "100%",
speed: 7000,
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 position = 0;
//var time = $('#danmu').data("nowTime")+1;
// var size = document.getElementById('text_size').value;
var size = 1;
//var text_obj='{ "text":"'+text+'","color":"'+color+'","size":"'+size+'","position":"'+position+'","time":'+time+'}';
//为了处理简单,方便后续加time,和isnew,就先酱紫发一半吧。
//注:time为弹幕出来的时间,isnew为是否加边框,自己发的弹幕,常理上来说是有边框的。
var text_obj = '{ "text":"' + text + '","color":"' + color + '","size":"' + size + '","position":"' + position + '", "roomid":"' + room.roomid + '"';
//利用websocket发送
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);
}
//获取url房间号
function GetRequest(urlStr) {
if (typeof urlStr == "undefined") {
var url = decodeURI(location.search); //获取url中"?"符后的字符串
} else {
var url = "?" + urlStr.split("?")[1];
}
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
}
}
return theRequest;
}
基础弹幕功能不再多说,说一下分房间弹幕:
第一种方法,原理js获取到roomid 在通讯时加上 ?roomid=xxx 此时在后端 open方法内可以拿到房间号 $roomId = $request->get['roomid']; 通过 push 传递给前端进行操作 $ws->push($request->fd, $roomId); 前端拿到房间号进行与当前房间号对比 判断是否为本房间进行弹幕显示。
第二种方法,直接在前端send时把房间号加上 var xx = '{"xxx": "xxx", "roomid": "roomid"}' ; websocket.send(xx); 此时在后端 message方法内获取到前端data 然后 直接push到前端 ,前端在onmessage方法内拿到后端push的数据进行房间号对比判断,是否为本房间进行弹幕显示。
两种方法原理都为判断roomid 深入研究可以存放弹幕(redis,系统内存,变量......),判断用户权限,轮播弹幕等,以上代码只为基础代码,有需要的同学可以学习一下。