WebSocket中的長連線以及逾時問題的解決問題(程式碼)
這篇文章帶給大家的內容是關於WebSocket中的長連結以及超時問題的解決問題(程式碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
<?php set_time_limit(0); class SocketService { private $address = 'localhost'; private $port = 80; private $_sockets; public function __construct($address = '', $port='') { if(!empty($address)){ $this->address = $address; } if(!empty($port)) { $this->port = $port; } } public function service(){ //获取tcp协议号码。 $tcp = getprotobyname("SOL_TCP"); # 获取与协议名称关联的协议号 $sock = socket_create(AF_INET, SOCK_STREAM, $tcp); # 创建一个套接字(通讯节点) socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1); # 设置套接字选项 if($sock < 0) { throw new Exception("failed to create socket: ".socket_strerror($sock)."\n"); } socket_bind($sock, $this->address, $this->port); # 绑定 socket_listen($sock, $this->port); # 监听套接字上的连接 $this->_sockets = $sock; } public function run(){ $this->service(); $clients[] = $this->_sockets; # 数组存储 每个socket # 让服务器无限获取客户端传过来的信息 while (true){ $changes = $clients; $write = NULL; $except = NULL; socket_select($changes, $write, $except, NULL); foreach ($changes as $key => $_sock){ if($this->_sockets == $_sock){ # 判断是不是新接入的socket if(($newClient = socket_accept($_sock)) === false){ # 接受新的套接字上的连接 socket_accept的作用就是接受socket_bind()所绑定的主机发过来的套接流 die('failed to accept socket: '.socket_strerror($_sock)."\n"); # 返回描述套接字错误的字符串 } $line = trim(socket_read($newClient, 1024)); # 读取客户端传过来的资源,并转化为字符串 socket_read的作用就是读出socket_accept()的资源并把它转化为字符串 $this->handshaking($newClient, $line); //获取client ip socket_getpeername ($newClient, $ip); # 查询给定套接字的远程端,这可能导致主机/端口或UNIX文件系统路径,具体取决于其类型。 $clients[$ip] = $newClient; } else { # 读取该socket的信息,注意:第二个参数是引用传参即接收数据,第三个参数是接收数据的长度 $lenght = socket_recv($_sock, $buffer, 2048, 0); # 从已连接的socket接收数据 $lenght 接收到字符串长度 $msg = $this->message($buffer); # 接收到的信息 //在这里业务代码 fwrite(STDOUT, 'Please input a argument:'); $response = trim(fgets(STDIN)); // $this->send($_sock, $response); # 第二个参数是获取数据 要发送的信息 $this->send($_sock, '在线'); } } } } /** * 握手处理 * @param $newClient socket * @return int 接收到的信息 */ public function handshaking($newClient, $line){ $headers = array(); $lines = preg_split("/\r\n/", $line); # 通过一个正则表达式分隔字符串。 foreach($lines as $line) { $line = chop($line); # 移除字符串右端的空白字符或其他预定义字符 if(preg_match('/\A(\S+): (.*)\z/', $line, $matches)) { $headers[$matches[1]] = $matches[2]; } } $secKey = $headers['Sec-WebSocket-Key']; $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))); $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "WebSocket-Origin: $this->address\r\n" . "WebSocket-Location: ws://$this->address:$this->port/服务器地址\r\n". "Sec-WebSocket-Accept:$secAccept\r\n\r\n"; return socket_write($newClient, $upgrade, strlen($upgrade)); # socket_write的作用是向socket_create的套接流写入信息,或者向socket_accept的套接流写入信息 } /** * 解析接收数据 * @param $buffer * @return null|string */ public function message($buffer){ $len = $masks = $data = $decoded = null; $len = ord($buffer[1]) & 127; if ($len === 126) { $masks = substr($buffer, 4, 4); $data = substr($buffer, 8); } else if ($len === 127) { $masks = substr($buffer, 10, 4); $data = substr($buffer, 14); } else { $masks = substr($buffer, 2, 4); $data = substr($buffer, 6); } for ($index = 0; $index < strlen($data); $index++) { $decoded .= $data[$index] ^ $masks[$index % 4]; } return $decoded; } /** * 发送数据 * @param $newClinet 新接入的socket * @param $msg 要发送的数据 * @return int|string */ public function send($newClinet, $msg){ $msg = $this->frame($msg); socket_write($newClinet, $msg, strlen($msg)); # 写入套接字 } public function frame($s) { $a = str_split($s, 125); # 把字符串分割到数组中 第二个长度参数 if (count($a) == 1) { return "\x81" . chr(strlen($a[0])) . $a[0]; } $ns = ""; foreach ($a as $o) { $ns .= "\x81" . chr(strlen($o)) . $o; } return $ns; } /** * 关闭socket */ public function close(){ # socket_close的作用是关闭socket_create()或者socket_accept()所建立的套接流 return socket_close($this->_sockets); } } $sock = new SocketService(); $sock->run();
網路上看到很多說會斷開連結,設定心跳包也沒有用
我這裡直接設定了下set_time_limit(0); 改變php.ini中的max_execution_time設定時間然後就沒有斷線的問題了! 也保證了持久連結!
HTML部分
<!DOCTYPE html> <html> <head> <title>Socket 测试</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no"> <link href="https://cdn.bootcss.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"> <style type="text/css"> html, body { min-height: 100%; } body { margin: 0; padding: 0; width: 100%; font-family: "Microsoft Yahei",sans-serif, Arial; } .container { text-align: center; } .title { font-size: 16px; color: rgba(0, 0, 0, 0.3); position: fixed; line-height: 30px; height: 30px; left: 0px; right: 0px; background-color: white; } .content { background-color: #f1f1f1; border-top-left-radius: 6px; border-top-right-radius: 6px; margin-top: 30px; } .content .show-area { text-align: left; padding-top: 8px; padding-bottom: 168px; } .content .show-area .message { width: 70%; padding: 5px; word-wrap: break-word; word-break: normal; } .content .write-area { position: fixed; bottom: 0px; right: 0px; left: 0px; background-color: #f1f1f1; z-index: 10; width: 100%; height: 160px; border-top: 1px solid #d8d8d8; } .content .write-area .send { position: relative; top: -28px; height: 28px; border-top-left-radius: 55px; border-top-right-radius: 55px; } .content .write-area #name{ position: relative; top: -20px; line-height: 28px; font-size: 13px; } </style> </head> <body> <div class="container"> <div class="title">Socket 测试长连接</div> <div class="content"> <div class="show-area"></div> <div class="write-area"> <div><button class="btn btn-default send" >发送</button></div> <div><input name="name" id="name" type="text" placeholder="input your name"></div> <div> <textarea name="message" id="message" cols="38" rows="4" placeholder="input your message..."></textarea> </div> </div> </div> </div> <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> <script> var wsurl = 'ws://localhost:80/websocket/test2.php'; var websocket; websocket = new WebSocket(wsurl); //连接建立 websocket.onopen = function(evevt){ console.log("Connected to WebSocket server."); $('.show-area').append('<p class="bg-info message"><i class="glyphicon glyphicon-info-sign"></i>Connected to WebSocket server!</p>'); } //收到消息 websocket.onmessage = function(event) { console.log(event); $('.show-area').append('<p class="bg-info message"><i class="glyphicon glyphicon-info-sign"></i>'+event.data+'</p>'); } //发生错误 websocket.onerror = function(event){ console.log("Connected to WebSocket server error"); $('.show-area').append('<p class="bg-danger message"><a name=""></a><i class="glyphicon glyphicon-info-sign"></i>Connect to WebSocket server error.</p>'); } //连接关闭 websocket.onclose = function(event){ console.log('websocket Connection Closed. '); $('.show-area').append('<p class="bg-warning message"><a name=""></a><i class="glyphicon glyphicon-info-sign"></i>websocket Connection Closed.</p>'); } // 发送信息 function send(){ var name = $('#name').val(); var message = $('#message').val(); if(!name){ alert('请输入用户名!'); return false; } if(!message){ alert('发送消息不能为空!'); return false; } var msg = { message: message, name: name }; try{ websocket.send(JSON.stringify(msg)); } catch(ex) { console.log(ex); } } //点发送按钮发送消息 $('.send').bind('click',function(){ send(); }); </script> </body> </html>
#
以上是WebSocket中的長連線以及逾時問題的解決問題(程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

隨著網路科技的不斷發展,即時通訊已經成為了日常生活中不可或缺的一部分。利用WebSockets技術可以實現高效、低延遲的即時通信,而PHP作為互聯網領域使用最廣泛的開發語言之一,也提供了相應的WebSocket支援。本文將為大家介紹如何使用PHP和WebSocket實現即時通信,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

隨著網路技術的不斷發展,即時視訊串流已成為了網路領域的重要應用。要實現即時視訊串流播放,其中的關鍵技術包括WebSocket和Java。本文將介紹如何結合使用WebSocket和Java實現即時視訊串流播放,並提供相關的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工通訊的協議,它在Web

golangWebSocket與JSON的結合:實現資料傳輸和解析在現代的Web開發中,即時資料傳輸變得越來越重要。 WebSocket是一種用於實現雙向通訊的協議,與傳統的HTTP請求-回應模型不同,WebSocket允許伺服器向客戶端主動推送資料。而JSON(JavaScriptObjectNotation)是一種用於資料交換的輕量級格式,它簡潔易讀

PHP和WebSocket:實現即時資料傳輸的最佳實踐方法引言:在Web應用程式開發中,即時資料傳輸是一項非常重要的技術需求。傳統的HTTP協定是一種請求-回應模式的協議,不能有效地實現即時資料傳輸。為了滿足即時資料傳輸的需求,WebSocket協定應運而生。 WebSocket是一種全雙工通訊協議,它提供了一種在單一TCP連接上進行全雙工通訊的方式。相比於H

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用Java和WebSocket實現即時股票行情推播引言:隨著網路的快速發展,股票行情即時推播成為了投資人關注的焦點之一。傳統的股票行情推送方式存在延遲較高、刷新速度慢等問題,對於投資人來說,無法及時獲得最新的股票行情資訊可能會導致投資決策的誤差。而基於Java和WebSocket的即時股票行情推送可以有效解決這個問題,使投資者能夠第一時間獲取到最新的

JavaWebsocket如何實現線上白板功能?在現代網路時代,人們越來越注重即時協作和互動的體驗。線上白板就是一種基於Websocket實現的功能,它能夠使多個使用者即時協作編輯同一個畫板,完成繪圖和標註等操作,為線上教育、遠端會議、團隊協作等場景提供了便捷的解決方案。一、技術背景WebSocket是HTML5提供的一種新的協議,它在同一條TCP連接上實
