swoole + websocket + js實現分房間彈幕

1.後端利用php 安裝swoole 不會的自行百度 不再贅述

創建 websocket.php文件

<?php 
//創建websocket服務器對象,監聽0.0.0.0:9505端口 自行修改端口
$ws = new swoole_websocket_server("192.168.18.15", 9505);

//監聽WebSocket連接打開事件
$ws->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,系統內存,變量......),判斷用戶權限,輪播彈幕等,以上代碼只爲基礎代碼,有需要的同學可以學習一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章