PHP實現(xiàn)web socket長鏈接流程詳解
簡介
目前PHP實現(xiàn)web socket 都是使用框架集成來實現(xiàn),比如hyperf,swoft,或者是安裝swoole 擴展來實現(xiàn)websocket,那么有沒有PHP本身就能夠?qū)崿F(xiàn)的呢,答案當然有,Let’s go.
函數(shù)介紹
服務(wù)端
stream_socket_server — Create an Internet or Unix domain server socket
可以幫我創(chuàng)建網(wǎng)絡(luò)鏈接具柄,參數(shù)如下
stream_socket_server(
string $address,
int &$error_code = null,
string &$error_message = null,
int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
?resource $context = null
): resource|false
客戶端
stream_socket_client — Open Internet or Unix domain socket connection
連接句柄
stream_socket_client(
string $address,
int &$error_code = null,
string &$error_message = null,
?float $timeout = null,
int $flags = STREAM_CLIENT_CONNECT,
?resource $context = null
): resource|false
簡單運用
<?php //服務(wù)端
$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) { //循環(huán) 等待鏈接
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");//成功鏈接輸出以上內(nèi)容 大致為:The local time is 3/22/2023 11:13 am
fclose($conn); //斷開連接
}
fclose($socket); //斷開socket
}
?>
<?php //客戶端
$fp = stream_socket_client("tcp://0.0.0.0:8000", $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n");
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);
}
?>
解釋
上面的事例,只能在服務(wù)器之間調(diào)用,而且每次鏈接都會斷開,一旦需要使用服務(wù)就需要不斷的進行連接,不斷的進行三次握手很浪費資源,那么能不能實現(xiàn)一個呢,No Code No BB.
JsDemo
// 創(chuàng)建websocket
ws = new WebSocket("ws://"+domain+"/"+port);
// 當socket連接打開時,輸入用戶名
ws.onopen = function(){}; //自定義 連接建立時處理操作,比如IM系統(tǒng)登陸信息操作
// 當有消息時根據(jù)消息類型顯示不同信息
ws.onmessage = function(){};// 操作服務(wù)端發(fā)來的消息
ws.onclose = function() {
console.log("連接關(guān)閉,定時重連");
connect();//重新連接
};
ws.onerror = function() {
console.log("出現(xiàn)錯誤");
};
PHP實現(xiàn)三次握手
$socket = stream_socket_server('tcp://'.$ipServer.':'.$portNumber, $errno, $errstr);
while($conn = @stream_socket_accept($socket,$nbSecondsIdle))
{
$message= fread($conn, 1024);
send($conn,$message);
//@todo
//連接成功,有要保持連接,用來接收客戶端發(fā)送過來的數(shù)據(jù)包 這里可以把這個連接$conn 保存在內(nèi)存當中,通過Select or Swoole 事件去loop
fputs ($conn, "OK\n");
}
function send($socket,$buffer){
$Sec_WebSocket_Key = '';
if (\preg_match("/Sec-WebSocket-Key: *(.*?)\r\n/i", $buffer, $match)) {
$Sec_WebSocket_Key = $match[1];
}
$new_key = \base64_encode(\sha1($Sec_WebSocket_Key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
$handshake_message = "HTTP/1.1 101 Switching Protocols\r\n"
."Upgrade: websocket\r\n"
."Sec-WebSocket-Version: 13\r\n"
."Connection: Upgrade\r\n"
."Sec-WebSocket-Accept: " . $new_key . "\r\n";
$handshake_message .= "\r\n";
var_dump($handshake_message);//打印握手信息,然后發(fā)送給客戶端,建立完整連接
//socket_write($socket,$handshake_message);
$len = @\fwrite($socket, $handshake_message);
return 0;
}
到此這篇關(guān)于PHP實現(xiàn)web socket長鏈接流程詳解的文章就介紹到這了,更多相關(guān)PHP web socket長鏈接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP設(shè)計模式之原型設(shè)計模式原理與用法分析
這篇文章主要介紹了PHP設(shè)計模式之原型設(shè)計模式,簡單描述了原型設(shè)計模式的概念、原理并結(jié)合實例形式分析了php原型設(shè)計模式的定義與使用方法,需要的朋友可以參考下2018-04-04
php5.5使用PHPMailer-5.2發(fā)送郵件的完整步驟
PHPMailer已經(jīng)更新了很多版本了,本教程只針對老版本。下面這篇文章主要給大家介紹了關(guān)于php5.5使用PHPMailer-5.2發(fā)送郵件的完整步驟,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10
php用數(shù)組返回無限分類的列表數(shù)據(jù)的代碼
php自定義函數(shù)之用數(shù)組返回無限分類的列表數(shù)據(jù),這樣的實現(xiàn)可以提高執(zhí)行的效率不要每次都從數(shù)據(jù)庫讀取數(shù)據(jù)。2010-08-08

