利用Swoole實現(xiàn)PHP+websocket 聊天室

websocket

Websocket只是一個網(wǎng)絡(luò)通信協(xié)議
就像 http惋嚎、ftp等都是網(wǎng)絡(luò)通信的協(xié)議;不要多想;
相對于HTTP這種非持久的協(xié)議來說,Websocket是一個持久化網(wǎng)絡(luò)通信的協(xié)議邻薯;

WebSocket和HTTP的關(guān)系

WebSocket和HTTP的關(guān)系


websocket+http.png

有交集,但是并不是全部乘凸。
Websocket只是借用了HTTP的一部分協(xié)議來完成一次握手厕诡。(HTTP的三次握手,此處只完成一次)

http和websocket 請求頭對比:

http請求頭.jpg

websocket請求頭.png

HTTP:
原來的時候营勤,客戶端通過http(騎馬)帶著信請求服務(wù)器木人,服務(wù)器處理請求(寫回信),再次通過http(騎馬)返回冀偶;鏈接斷開醒第;

WebSocket:
客戶端通過http(騎馬)帶著信請求服務(wù)器,但同時进鸠,攜帶了Upgrade:websocket和Connection:Upgrade(兩根管子),服務(wù)器如果支持WebSocket協(xié)議(有兩根管子的接口)稠曼,使用Websocket協(xié)議返回可用信息(丟棄馬匹),此后信息的傳遞客年,均使用這兩個管子霞幅,除非有一方人為的將管子切斷;若服務(wù)器不支持,客戶端請求鏈接失敗量瓜,返回錯誤信息司恳;

http和websocket 響應(yīng)頭對比:


http響應(yīng)頭.jpg

websocket響應(yīng)頭.jpg

websocket和ajax輪詢、long poll的區(qū)別

首先是 ajax輪詢 绍傲,ajax輪詢的原理非常簡單扔傅,讓瀏覽器隔個幾秒就發(fā)送一次請求,詢問服務(wù)器是否有新信息
場景再現(xiàn):
客戶端:啦啦啦烫饼,有沒有新信息(Request)
服務(wù)端:沒有(Response)
客戶端:啦啦啦猎塞,有沒有新信息(Request)
服務(wù)端:沒有。杠纵。(Response)
客戶端:啦啦啦荠耽,有沒有新信息(Request)
服務(wù)端:你好煩啊,沒有啊比藻。铝量。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務(wù)端:好啦好啦银亲,有啦給你慢叨。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務(wù)端:群凶。插爹。。沒。赠尾。力穗。。沒气嫁。当窗。沒有

long poll 其實原理跟 ajax輪詢 差不多,都是采用輪詢的方式,不在論述寸宵;

從上面可以看出崖面,輪詢其實就是在不斷地建立HTTP連接,然后等待服務(wù)端處理梯影,可以體現(xiàn)HTTP協(xié)議的另外一個特點巫员,被動性。同時甲棍,http的每一次請求與響應(yīng)結(jié)束后简识,服務(wù)器將客戶端信息全部丟棄,下次請求感猛,必須攜帶身份信息(cookie)七扰,無狀態(tài)性

Websocket的出現(xiàn)陪白,干凈利落的解決了這些問題颈走;

所以上面的情景可以做如下修改。
客戶端:啦啦啦咱士,我要建立Websocket協(xié)議立由,需要的服務(wù):chat,Websocket協(xié)議版本:17(HTTP Request)
服務(wù)端:ok司致,確認(rèn)拆吆,已升級為Websocket協(xié)議(HTTP Protocols Switched)
客戶端:麻煩你有信息的時候推送給我噢。脂矫。
服務(wù)端:ok,有的時候會告訴你的霉晕。
客戶端:balab開始斗圖alabala
服務(wù)端:蒼井空ala
客戶端:流鼻血了庭再,我擦……
服務(wù)端:哈哈布爾教育牛逼啊哈哈哈哈
服務(wù)端:笑死我了哈哈

Swoole

但是,為了用PHP配合HTML5完成一次WebSocket請求和響應(yīng)牺堰,哥走過千山萬水拄轻,在密林深處,發(fā)現(xiàn)了Swoole : http://www.swoole.com/;

PHP語言的異步伟葫、并行恨搓、高性能網(wǎng)絡(luò)通信框架,使用純C語言編寫,提供了PHP語言的異步多線程服務(wù)器斧抱,異步TCP/UDP網(wǎng)絡(luò)客戶端常拓,異步MySQL,數(shù)據(jù)庫連接池辉浦,AsyncTask弄抬,消息隊列,毫秒定時器宪郊,異步文件讀寫掂恕,異步DNS查詢。
支持的服務(wù):
HttpServer
WebSocket Server
TCP Server
TCP Client
Async-IO(異步)
Task(定時任務(wù))

環(huán)境依賴:
僅支持Linux弛槐,F(xiàn)reeBSD懊亡,MacOS,3類操作系統(tǒng)
Linux內(nèi)核版本2.3.32以上
PHP5.3.10以上版本
gcc4.4以上版本或者clang
cmake2.4+乎串,編譯為libswoole.so作為C/C++庫時需要使用cmake

安裝:
必須保證系統(tǒng)中有以下這些軟件:
php-5.3.10 或更高版本
gcc-4.4 或更高版本
make
autoconf

Swoole是作為PHP擴(kuò)展來運行的

安裝(root權(quán)限):
cd swoole
phpize
./configure
make
sudo make install
配置php.ini
extension=swoole.so

想研究Swoole的同學(xué)店枣,自己去看手冊(雖然寫的不好,但是還是能看懂的)

做一個聊天室

服務(wù)器端:socket.php


//創(chuàng)建websocket服務(wù)器對象灌闺,監(jiān)聽0.0.0.0:9502端口
$ws = new swoole_websocket_server("0.0.0.0", 9502);
$ws->user_c = [];   //給ws對象添加屬性user_c艰争,值為空數(shù)組;
//監(jiān)聽WebSocket連接打開事件
$ws->on('open', function ($ws, $request) {
    $ws->user_c[] = $request->fd;
    //$ws->push($request->fd, "hello, welcome\n");
});

//監(jiān)聽WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
    $msg =  'from'.$frame->fd.":{$frame->data}\n";
   foreach($ws->user_c as $v){
      $ws->push($v,$msg);
  }
   // $ws->push($frame->fd, "server: {$frame->data}");
    // $ws->push($frame->fd, "server: {$frame->data}");
});

//監(jiān)聽WebSocket連接關(guān)閉事件
$ws->on('close', function ($ws, $fd) {
    //刪除已斷開的客戶端
    unset($ws->user_c[$fd-1]);
});

$ws->start();

客戶端:Socket.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="msg"></div>
<input type="text" id="text">
<input type="submit" value="發(fā)送數(shù)據(jù)" onclick="song()">
</body>
<script>
    var msg = document.getElementById("msg");
    var wsServer = 'ws://192.168.1.253:9502';
    //調(diào)用websocket對象建立連接:
    //參數(shù):ws/wss(加密)://ip:port (字符串)
    var websocket = new WebSocket(wsServer);
    //onopen監(jiān)聽連接打開
    websocket.onopen = function (evt) {
        //websocket.readyState 屬性:
        /*
        CONNECTING  0   The connection is not yet open.
        OPEN    1   The connection is open and ready to communicate.
        CLOSING 2   The connection is in the process of closing.
        CLOSED  3   The connection is closed or couldn't be opened.
        */
        msg.innerHTML = websocket.readyState;
    };

    function song(){
        var text = document.getElementById('text').value;
        document.getElementById('text').value = '';
        //向服務(wù)器發(fā)送數(shù)據(jù)
        websocket.send(text);
    }
      //監(jiān)聽連接關(guān)閉
//    websocket.onclose = function (evt) {
//        console.log("Disconnected");
//    };

    //onmessage 監(jiān)聽服務(wù)器數(shù)據(jù)推送
    websocket.onmessage = function (evt) {
        msg.innerHTML += evt.data +'<br>';
//        console.log('Retrieved data from server: ' + evt.data);
    };
//監(jiān)聽連接錯誤信息
//    websocket.onerror = function (evt, e) {
//        console.log('Error occured: ' + evt.data);
//    };

</script>
</html>

websocket API 手冊:
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桂对,一起剝皮案震驚了整個濱河市甩卓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蕉斜,老刑警劉巖逾柿,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宅此,居然都是意外死亡机错,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門父腕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弱匪,“玉大人,你說我怎么就攤上這事璧亮∠艚耄” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵枝嘶,是天一觀的道長帘饶。 經(jīng)常有香客問我,道長群扶,這世上最難降的妖魔是什么及刻? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任镀裤,我火速辦了婚禮,結(jié)果婚禮上缴饭,老公的妹妹穿的比我還像新娘暑劝。我一直安慰自己,他們只是感情好茴扁,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布铃岔。 她就那樣靜靜地躺著,像睡著了一般峭火。 火紅的嫁衣襯著肌膚如雪毁习。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天卖丸,我揣著相機(jī)與錄音纺且,去河邊找鬼。 笑死稍浆,一個胖子當(dāng)著我的面吹牛载碌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衅枫,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嫁艇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弦撩?” 一聲冷哼從身側(cè)響起步咪,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎益楼,沒想到半個月后猾漫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡感凤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年悯周,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陪竿。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡禽翼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出族跛,到底是詐尸還是另有隱情捐康,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布庸蔼,位于F島的核電站,受9級特大地震影響贮匕,放射性物質(zhì)發(fā)生泄漏姐仅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掏膏。 院中可真熱鬧劳翰,春花似錦、人聲如沸馒疹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颖变。三九已至生均,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腥刹,已是汗流浹背马胧。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留衔峰,地道東北人佩脊。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像垫卤,于是被迫代替她去往敵國和親威彰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理穴肘,服務(wù)發(fā)現(xiàn)歇盼,斷路器,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • WebSocket簡介 談到Web實時推送梢褐,就不得不說WebSocket旺遮。在WebSocket出現(xiàn)之前,很多網(wǎng)站為...
    吧啦啦小湯圓閱讀 8,145評論 15 75
  • Websocket只是一個網(wǎng)絡(luò)通信協(xié)議就像 http盈咳、ftp等都是網(wǎng)絡(luò)通信的協(xié)議耿眉;不要多想;相對于HTTP這種非持...
    布爾教育閱讀 498評論 0 1
  • 傅斯年鄙視錢穆。錢的《國史大綱》新鮮出爐丈积,洛陽紙貴筐骇,好事者問傅對該書怎么看。 “不看江滨☆跷常” 我想這才是對本片應(yīng)該有的...
    冬工廠閱讀 2,194評論 0 2
  • 7月21日咖啡冥想 1、家里最近修窯洞唬滑,是小姐夫告唆、三哥棺弊、老公三個人干活,大姐昨天回去做飯擒悬,大哥也送來西瓜模她,老公昨晚...