隨著WEB2.0的流行,現(xiàn)在很多網(wǎng)站都流行使用“彈幕”這種形式來實(shí)現(xiàn)互動(dòng)。
創(chuàng)新互聯(lián)公司主要從事網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)梁河,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220
彈幕(barrage),中文流行詞語,原意指用大量或少量火炮提供密集炮擊。大量以字幕彈(dàn)出形式顯示的評論同時(shí)在屏幕上飄過的現(xiàn)象也被稱為彈幕。
作為PHPer的我們,看到現(xiàn)在各種網(wǎng)站都有酷炫的彈幕飛過,我們是不是也想給自己的網(wǎng)站加入彈幕功能呢?
首先彈幕的后端其實(shí)說白了和公共聊天室的后端原理十分相似,都是一個(gè)客戶端發(fā)送消息給服務(wù)端,服務(wù)端再將收到的消息廣播給其他的客戶端。對于后端來說他們幾乎沒區(qū)別,區(qū)別就在于前端。
好在我們有一個(gè)前端彈幕插件,這個(gè)插件是一個(gè)jquery插件,github地址:,基本上會使用jquery語法,看看示例代碼就可以傻瓜化使用。
前端已經(jīng)有了解決方案,但是后端呢?前端如何與后端通訊?用傳統(tǒng)的ajax輪詢嗎?不行,這樣效率太低,想想各大火爆的直播平臺都是同一時(shí)間幾萬人在線,幾千人同時(shí)發(fā)彈幕,如果靠ajax輪詢一個(gè)php接口的話服務(wù)器會吃不消的。且彈幕消息存儲方案略顯復(fù)雜,有人問為什么要存儲呢?因?yàn)閍jax使用的HTTP協(xié)議是無狀態(tài)協(xié)議,A客戶端和B客戶端之間對于服務(wù)器來說沒有任何標(biāo)志,如果服務(wù)器要確保A客戶端和B客戶端分別在兩次請求的時(shí)候服務(wù)器只返回這兩個(gè)客戶端沒有獲取過的彈幕消息,那么服務(wù)器端就必須使用一個(gè)緩存來標(biāo)識某某客戶端看過哪條彈幕消息。綜上所述ajax可以實(shí)現(xiàn)小規(guī)模的彈幕通信方案,但是很麻煩。
好在最新的HTML5中加入了WebSocket協(xié)議,我們可以通過WebSocket這種基于HTTP協(xié)議之上的即時(shí)通信協(xié)議來替代ajax這種傳統(tǒng)的我問你答的老舊通信模式。而我們是PHPer,對于我們這種只懂PHP的人該如何編寫WebSocket服務(wù)端呢?好在我們又得知PHP有一個(gè)Swoole擴(kuò)展,我們在PHP語言中使用它可以很方便的構(gòu)建一個(gè)WebSocket服務(wù)端。
關(guān)于Swoole的介紹可以參照他的官網(wǎng),下面引用官網(wǎng)對它的一段簡短的介紹。
PHP的異步、并行、高性能網(wǎng)絡(luò)通信引擎,使用純C語言編寫,提供了PHP語言的異步多線程服務(wù)器,異步TCP/UDP網(wǎng)絡(luò)客戶端,異步MySQL,異步Redis,數(shù)據(jù)庫連接池,AsyncTask,消息隊(duì)列,毫秒定時(shí)器,異步文件讀寫,異步DNS查詢。 Swoole內(nèi)置了Http/WebSocket服務(wù)器端/客戶端、Http2.0服務(wù)器端。
Swoole可以廣泛應(yīng)用于互聯(lián)網(wǎng)、移動(dòng)通信、企業(yè)軟件、云計(jì)算、網(wǎng)絡(luò)游戲、物聯(lián)網(wǎng)(IOT)、車聯(lián)網(wǎng)、智能家居等領(lǐng)域。 使用PHP+Swoole作為網(wǎng)絡(luò)通信框架,可以使企業(yè)IT研發(fā)團(tuán)隊(duì)的效率大大提升,更加專注于開發(fā)創(chuàng)新產(chǎn)品。
先別被Swoole這么多的功能嚇到了。我們先關(guān)注這里面的重點(diǎn)Swoole內(nèi)置了Http/WebSocket服務(wù)器端/客戶端意味著我們可以通過它構(gòu)建WebSocket的服務(wù)端??吹竭@里我們是不是就急急忙忙去拿官網(wǎng)的WebSocket服務(wù)端代碼做測試呢?不,Swoole是一個(gè)PHP擴(kuò)展,意味著我們還得去安裝它。是不是直接去下載so文件然后在php.ini中加入extension=swoole.so就可以了呢?還不是,我們先去看看Swoole擴(kuò)展的依賴,這也是我們使用任何語言的任何外部包,外部模塊,外部擴(kuò)展最先要了解的問題。
參考官網(wǎng):環(huán)境依賴
僅支持Linux,F(xiàn)reeBSD,MacOS,3類操作系統(tǒng)
Linux內(nèi)核版本2.3.32以上
PHP5.3.10以上版本,包括PHP7
gcc4.4以上版本或者clang
cmake2.4+,編譯為libswoole.so作為C/C++庫時(shí)需要使用cmakePHP版本依賴
swoole僅支持PHP5.3.10或更高版本,建議使用PHP5.4+swoole不依賴php的stream、sockets、pcntl、posix、sysvmsg等擴(kuò)展。PHP只需安裝最基本的擴(kuò)展即可意味著我們Windows下是無法使用這個(gè)擴(kuò)展了(其實(shí)可以借助cygwin在win下使用swoole,但是考慮到我們使用swoole擴(kuò)展就是為了性能,也為了熟悉以后的生產(chǎn)環(huán)節(jié)部署做準(zhǔn)備,強(qiáng)烈推薦在linux下開發(fā)),那么我們把開發(fā)環(huán)境轉(zhuǎn)移到Linux下進(jìn)行吧。
接著還要求Linux內(nèi)核版本為2.3.32以上,PHP為5.3.10以上,那么我們就用最新的CentOS吧,這個(gè)版本的yum安裝的php直接就是PHP7最新版,根本無需考慮其他問題,當(dāng)然你喜歡圖形界面,用Ubuntu也可以。其他的基本上最新的Linux發(fā)行版都是符合版本要求的。
接著我們便來安裝這個(gè)擴(kuò)展,推薦使用PECL來安裝,只需要一條pecl install swoole
即可,非常方便。當(dāng)然你要編譯安裝,具體步驟請參考安裝完擴(kuò)展之后在命令行下輸入
php -m
檢查,如果有swoole那么說明安裝成功了。
接下來就正式開始我們的編碼旅程了。
開始編碼旅程之前我們先看看最基礎(chǔ)的效果原型是什么樣子沒錯(cuò)就是這個(gè)樣子,兩個(gè)瀏覽器之前完全獨(dú)立使用Websocket連接服務(wù)端,因此對于服務(wù)端來說這兩個(gè)瀏覽器就相當(dāng)于兩個(gè)完全處在不同機(jī)器上的客戶端。
效果看完了就開始來講代碼吧。
我們先看看官網(wǎng)的WebSocket服務(wù)端示例代碼。
$serv = new Swoole\Websocket\Server("127.0.0.1", 9502);$serv-on('Open', function($server, $req) {echo "connection open: ".$req-fd;
});
$serv-on('Message', function($server, $frame) {echo "message: ".$frame-data;
$server-push($frame-fd, json_encode(["hello", "world"]));});
$serv-on('Close', function($server, $fd) {echo "connection close: ".$fd;
});
$serv-start();
我們看到這個(gè)代碼的第一行先是new了一個(gè)WebSocket服務(wù)端對象,并且在構(gòu)造方法中的第一個(gè)參數(shù)指定了服務(wù)端監(jiān)聽的IP,第二個(gè)參數(shù)指定了服務(wù)端監(jiān)聽的端口。然后使用on方法為每一個(gè)事件設(shè)置了回調(diào)函數(shù),最后一行start方法正式開始運(yùn)行服務(wù)端。
這種寫法非常像Javascript里面的異步調(diào)用,這也是Swoole中的事件驅(qū)動(dòng)異步非阻塞特性,正因?yàn)槭沁@種特性,每一個(gè)獨(dú)立的事件(請求)會在服務(wù)端接收到之后分別異步處理,他們之間無需互相等待,這也是Swoole性能高的原因所在。
我們來分別剖析一下每一個(gè)事件的含義。
$serv-on('Open', function($server, $req) {echo "connection open: ".$req-fd;
});
顧名思義,Open表示打開一個(gè)新的鏈接,并且在事件觸發(fā)之后echo出連接上服務(wù)端的客戶端id,該客戶端唯一id為回調(diào)函數(shù)第二個(gè)參數(shù)中的fd字段。這也是服務(wù)端區(qū)分客戶端的唯一id。
$serv-on('Message', function($server, $frame) {echo "message: ".$frame-data;
$server-push($frame-fd, json_encode(["hello", "world"]));});
同樣顧名思義,Message表示消息到達(dá)服務(wù)端的事件,并且在事件觸發(fā)之后echo出發(fā)送給服務(wù)端的數(shù)據(jù),該數(shù)據(jù)為回調(diào)函數(shù)第二個(gè)參數(shù)的data字段。另外我們還看到它調(diào)用了$server-push,這是回調(diào)函數(shù)的第一個(gè)參數(shù)中的push方法,它是一個(gè)服務(wù)端給客戶的發(fā)送數(shù)據(jù)的方法,第一個(gè)參數(shù)為要發(fā)送的客戶端id,第二個(gè)為要發(fā)送的數(shù)據(jù),這里的含義是向發(fā)給服務(wù)端消息的那個(gè)客戶端發(fā)送["hello", "world"]這個(gè)數(shù)組(方括號寫數(shù)組為PHP5.4的新特性,如果你是PHP5.3請使用傳統(tǒng)的array工廠函數(shù)生成數(shù)組)經(jīng)過json序列化之后的數(shù)據(jù)。
$serv-on('Close', function($server, $fd) {echo "connection close: ".$fd;
});
最后一個(gè)事件Close更加容易理解,就是關(guān)閉事件,當(dāng)然關(guān)閉的不是服務(wù)端,而是客戶端,可以理解為客戶端與服務(wù)端斷開連接的事件?;卣{(diào)函數(shù)中的代碼含義為echo出與服務(wù)端斷開連接的那個(gè)客戶端id。
基本的API都清楚了,下面就直接看代碼吧,短短二十行而已。
= new swoole_websocket_server("0.0.0.0", 1997);$server-on('open', function (swoole_websocket_server $server, $request) {echo "server: handshake success with fd{$request-fd}\n";//$request-fd 是客戶端id});
$server-on('message', function (swoole_websocket_server $server, $frame) {echo "receive from {$frame-fd}:{$frame-data},opcode:{$frame-opcode},fin:{$frame-finish}\n";//$frame-fd 是客戶端id,$frame-data是客戶端發(fā)送的數(shù)據(jù)//服務(wù)端向客戶端發(fā)送數(shù)據(jù)是用 $server-push( '客戶端id' , '內(nèi)容')$data = $frame-data;
foreach($server-connections as $fd){
$server-push($fd , $data);//循環(huán)廣播
}
});
$server-on('close', function ($ser, $fd) {echo "client {$fd} closed\n";
});
$server-start();
這里最核心的廣播代碼其實(shí)還用到了一個(gè)之前沒有提到過的成員,也就是swoole_websocket_server對象的connections成員,這個(gè)成員中保存了所有已連接上該WebSocket服務(wù)端的fd,也就是客戶端id。因此我們只要在message事件中使用foreach遍歷該成員,循環(huán)將所有服務(wù)端收到的彈幕消息都發(fā)送給其他已連接上該服務(wù)端的客戶端即可。
后端講完了再講講前端吧。
前端代碼也不是很多 ws = new WebSocket("ws://192.168.1.107:1997");ws.onopen = function(){
console.log("握手成功");
ws.send('hello world!!!');
};
ws.onmessage = function(e){
console.log("message:" + e.data);
var time = jQuery('#danmu').data("nowtime") + 1;var text_obj = '{ "text":"' + e.data + '" , "color":"green" ,"size":"1","position":"0","time":"' + time + '" ,"isnew":" "}'; //構(gòu)造加上了innew屬性的字符串danmu對象console.log(text_obj);
var new_obj = eval('(' + text_obj + ')'); //轉(zhuǎn)化為js對象jQuery('#danmu').danmu("add_danmu", new_obj); //向插件中添加該danmu對象};
ws.onerror = function(){
console.log("error");
};
核心代碼都在這里,使用new WebSocket("ws://192.168.1.107:1997")創(chuàng)建一個(gè)WebSocket客戶端連接對象,通過該對象的各種事件進(jìn)行對應(yīng)的操作,和服務(wù)端是不是很像?更多代碼解釋可以參考源代碼中的注釋,這里不做更多介紹。
看到這里相信作為一名PHPer的你也可以開發(fā)出屬于自己的彈幕系統(tǒng)了。這里展示的只是一個(gè)最基礎(chǔ)最原始的彈幕平臺。我們也了解到了使用PHP開發(fā)一個(gè)彈幕平臺需要涉及到的技術(shù)有WebSocket,Swoole擴(kuò)展,甚至碰到了很多初級開發(fā)者平時(shí)不怎么接觸的工具,比如說PECL,比如說Linux。
其實(shí)PHP結(jié)合Swoole擴(kuò)展還可以做很多事情,比如說對接各種家電,對接各種硬件接口實(shí)現(xiàn)在Web端實(shí)時(shí)控制家電,又比如說結(jié)合樹莓派做智能小車,通過web端進(jìn)行遙控等等,各種新奇的玩法等你發(fā)現(xiàn)。誰說PHP只能做Web開發(fā)?PHP擁有了Swoole擴(kuò)展其實(shí)能做的事情還有很多,Swoole就像他的宣傳標(biāo)題一樣:重新定義PHP。
最好用php的擴(kuò)展,swoole來寫,PHP底層對websocket的支持不是很好。用swoole建立長連接來推送彈幕
示范一下
a
href="#"
onclick='if(confirm("你確定要修改嗎?"))
{location.href="change.php";}'修改/a
當(dāng)你點(diǎn)擊修改的時(shí)候,會跳出這個(gè)問你“確定修改”的對話框,你確定的話,自動(dòng)跳到change.php執(zhí)行代碼;否則在本頁面不動(dòng)
order.php?detail=ID(2011072500001). $_GET['detail'] ;獲取ID,并安全處理后進(jìn)行SQL語句執(zhí)行。 之后將返回的SQL結(jié)果,顯示在HTML中,就可以嘞。
html
head
script ...
function send_request()
{
//ajax發(fā)送查找數(shù)據(jù)庫請求
//設(shè)置onready函數(shù)等待數(shù)據(jù)接收完成
//當(dāng)數(shù)據(jù)接收完成,將div id="data_recv"/div之間的innerHtml設(shè)置為接受到的數(shù)據(jù)
//并顯示該div(初始化時(shí)設(shè)置為隱藏)
}
/script
/head
body
//搜索部分
div id="data_recv"
/div
/body
/html
......php文件
根據(jù)發(fā)送來的請求搜索數(shù)據(jù)庫,并生成相應(yīng)的 html,然后echo 之
目前還沒有現(xiàn)成的套站程序,只有php源碼,你要會php的話可以自行制作,上面網(wǎng)站有php源碼
網(wǎng)站欄目:php結(jié)合數(shù)據(jù)庫實(shí)現(xiàn)彈幕,php彈幕技術(shù)
網(wǎng)頁鏈接:http://jinyejixie.com/article42/hsohhc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、網(wǎng)站制作、Google、外貿(mào)建站、云服務(wù)器、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)