websocket
Websocket只是一個網路通訊協定
就像 http、ftp等都是網路通訊的協定;不要多想;
相對於HTTP這種非持久的協定來說,Websocket是一個持久化網路通訊的協定;
WebSocket和HTTP的關係
有交集,但是並不是全部。
Websocket只是藉用了HTTP的一部分協定來完成一次握手。 (HTTP的三次握手,此處只完成一次)
http和websocket 請求頭對比:
HTTP:
原來的時候,客戶端透過http(騎馬)帶著信請求伺服器,伺服器處理請求(寫回信),再次透過http(騎馬)返回;連結斷開;
WebSocket:
客戶端透過http(騎馬)帶著信請求伺服器,但同時,攜帶了Upgrade:websocket
和Connection:Upgrade
(兩根管子),伺服器如果支援WebSocket協定(有兩根管子的介面) ,使用Websocket協議返回可用信息(丟棄馬匹),此後信息的傳遞,均使用這兩個管子,除非有一方人為的將管子切斷;若服務器不支持,客戶端請求鏈接失敗,返回錯誤信息;
http和websocket 回應頭對比:
websocket和ajax輪詢、long poll的區別
首先是 ajax輪詢 ,ajax輪詢的原理非常簡單,讓瀏覽器隔幾秒鐘就發送一次請求,詢問伺服器是否有新資訊
場景再現:
客戶端:啦啦啦,有沒有新資訊(Request)
服務端:沒有(Response)
客戶端:啦啦啦,有沒有新資訊(Request)
服務端:沒有。 。 (Response)
客戶端:啦啦啦,有沒有新資訊(Request)
服務端:你好煩啊,沒有啊。 。 (Response)
客戶端:啦啦啦,有沒有新訊息(Request)
服務端:好啦好啦,有啦給你。 (Response)
客戶端:啦啦啦,有沒有新訊息(Request)
服務端:。 。 。沒。 。 。 。沒。 。沒有
long poll 其實原理跟 ajax輪詢 差不多,都是採用輪詢的方式,不在論述;
從上面可以看出,輪詢其實就是在不斷地建立HTTP連接,然後等待服務端處理,可以體現HTTP協定的另一個特點,被動性。同時,http的每一次請求與回應結束後,伺服器將客戶端資訊全部丟棄,下次請求,必須攜帶身分資訊(cookie),無狀態性;
Websocket的出現,乾淨俐落的解決了這些問題;
所以上面的情景可以做如下修改。
客戶端:啦啦啦,我要建立Websocket協議,需要的服務:chat,Websocket協定版本:17(HTTP Request)
服務端:ok,確認,已升級為Websocket協定(HTTP Protocols Switched)
客戶端:麻煩你有訊息的時候推給我噢。 。
服務端:ok,有的時候會告訴你的。
客戶端:balab開始鬥圖alabala
服務端:蒼井空ala
客戶端:流鼻血了,我擦…
服務端:哈哈布爾教育牛逼啊哈哈哈哈
服務端:笑死我了哈哈
Swoole
但是,為了用PHP配合HTML5完成一次WebSocket請求和回應,哥走過千山萬水,在密林深處,發現了Swoole :
PHP語言的非同步、平行、高效能網路通訊框架,使用純C語言編寫,提供了PHP語言的非同步多執行緒伺服器,非同步TCP/UDP網路用戶端,異步MySQL,資料庫連接池,AsyncTask,訊息佇列,毫秒定時器,非同步檔案讀寫,非同步DNS查詢。
支援的服務:
HttpServer
WebSocket Server
TCP Server
TCP Client
Async-IO(非同步)
Task(定時任務)
環境依賴:
僅支援Linux,FreeBSD,MacOS,3類作業系統
Linux核心版本2.3.32以上
PHP5.3.10以上版本
gcc4.4以上版本或clang
cmake2.4+,編譯為libswoole.so作為C/C++函式庫時需要使用cmake
安裝:
必須保證系統中有以下這些軟體:
php-5.3.10 或更高版本
gcc-4.4 或更高版本
make
autoconf
Swoole是作為PHP擴充來運作的
安裝(root權限):
cd swoole
phpize
./configure
make
sudo make install
配置php.ini
extension=swoole.so
想研究Swoole的同學,自己去看手冊(雖然寫的不好,但是還是能看懂的)
做一個聊天室
伺服器端:socket.php
//创建websocket服务器对象,监听0.0.0.0:9502端口 $ws = new swoole_websocket_server("0.0.0.0", 9502); //监听WebSocket连接打开事件 $ws->on('open', function ($ws, $request) { $fd[] = $request->fd; $GLOBALS['fd'][] = $fd; //$ws->push($request->fd, "hello, welcome\n"); }); //监听WebSocket消息事件 $ws->on('message', function ($ws, $frame) { $msg = 'from'.$frame->fd.":{$frame->data}\n"; //var_dump($GLOBALS['fd']); //exit; foreach($GLOBALS['fd'] as $aa){ foreach($aa as $i){ $ws->push($i,$msg); } } // $ws->push($frame->fd, "server: {$frame->data}"); // $ws->push($frame->fd, "server: {$frame->data}"); }); //监听WebSocket连接关闭事件 $ws->on('close', function ($ws, $fd) { echo "client-{$fd} is closed\n"; }); $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="发送数据" onclick="song()"> </body> <script> var msg = document.getElementById("msg"); var wsServer = 'ws://192.168.1.253:9502'; //调用websocket对象建立连接: //参数:ws/wss(加密)://ip:port (字符串) var websocket = new WebSocket(wsServer); //onopen监听连接打开 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 = ''; //向服务器发送数据 websocket.send(text); } //监听连接关闭 // websocket.onclose = function (evt) { // console.log("Disconnected"); // }; //onmessage 监听服务器数据推送 websocket.onmessage = function (evt) { msg.innerHTML += evt.data +'<br>'; // console.log('Retrieved data from server: ' + evt.data); }; //监听连接错误信息 // websocket.onerror = function (evt, e) { // console.log('Error occured: ' + evt.data); // }; </script> </html>
以上就是基於Swoole實現PHP與websocket聊天室的全部內容,相信本文對大家學習PHP和websocket及開發聊天室很有幫助。