Home Backend Development PHP Tutorial Long connections and timeout issues in WebSocket (code)

Long connections and timeout issues in WebSocket (code)

Jan 12, 2019 am 10:01 AM
websocket

This article brings you content about long connections and timeout problems in WebSocket (code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

<?php
set_time_limit(0);
class SocketService
{
    private $address  = &#39;localhost&#39;;
    private $port = 80;
    private $_sockets;
    public function __construct($address = &#39;&#39;, $port=&#39;&#39;)
    {
        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(&#39;failed to accept socket: &#39;.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, &#39;Please input a argument:&#39;);
                    $response = trim(fgets(STDIN));
//                    $this->send($_sock, $response);                                                       # 第二个参数是获取数据    要发送的信息
                    $this->send($_sock, &#39;在线&#39;);
                }
            }
        }
    }

    /**
     * 握手处理
     * @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(&#39;/\A(\S+): (.*)\z/&#39;, $line, $matches))
            {
                $headers[$matches[1]] = $matches[2];
            }
        }
        $secKey = $headers[&#39;Sec-WebSocket-Key&#39;];
        $secAccept = base64_encode(pack(&#39;H*&#39;, sha1($secKey . &#39;258EAFA5-E914-47DA-95CA-C5AB0DC85B11&#39;)));
        $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();
Copy after login


I saw a lot on the Internet saying that the link will be disconnected, and setting the heartbeat package is useless

I configured it directly here set_time_limit(0); Change the max_execution_time setting time in php.ini and there will be no disconnection problem! It also ensures a persistent connection!

HTML part


<!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 = &#39;ws://localhost:80/websocket/test2.php&#39;;
        var websocket;
        websocket = new WebSocket(wsurl);
            //连接建立
            websocket.onopen = function(evevt){
                console.log("Connected to WebSocket server.");
                $(&#39;.show-area&#39;).append(&#39;<p class="bg-info message"><i class="glyphicon glyphicon-info-sign"></i>Connected to WebSocket server!</p>&#39;);
            }
            //收到消息
            websocket.onmessage = function(event) {
                console.log(event);
                $(&#39;.show-area&#39;).append(&#39;<p class="bg-info message"><i class="glyphicon glyphicon-info-sign"></i>&#39;+event.data+&#39;</p>&#39;);
            }

            //发生错误
            websocket.onerror = function(event){
                console.log("Connected to WebSocket server error");
                $(&#39;.show-area&#39;).append(&#39;<p class="bg-danger message"><a name=""></a><i class="glyphicon glyphicon-info-sign"></i>Connect to WebSocket server error.</p>&#39;);
            }

            //连接关闭
            websocket.onclose = function(event){
                console.log(&#39;websocket Connection Closed. &#39;);
                $(&#39;.show-area&#39;).append(&#39;<p class="bg-warning message"><a name=""></a><i class="glyphicon glyphicon-info-sign"></i>websocket Connection Closed.</p>&#39;);
            }

    // 发送信息
            function send(){
                var name = $(&#39;#name&#39;).val();
                var message = $(&#39;#message&#39;).val();
                if(!name){
                    alert(&#39;请输入用户名!&#39;);
                    return false;
                }
                if(!message){
                    alert(&#39;发送消息不能为空!&#39;);
                    return false;
                }
                 var msg = {
                     message: message,
                     name: name
                 };
                try{
                     websocket.send(JSON.stringify(msg));
                } catch(ex) {
                    console.log(ex);
                }
            }
            //点发送按钮发送消息
            $(&#39;.send&#39;).bind(&#39;click&#39;,function(){
                send();
            });

</script>
</body>
</html>
Copy after login


##

The above is the detailed content of Long connections and timeout issues in WebSocket (code). For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to achieve real-time communication using PHP and WebSocket How to achieve real-time communication using PHP and WebSocket Dec 17, 2023 pm 10:24 PM

With the continuous development of Internet technology, real-time communication has become an indispensable part of daily life. Efficient, low-latency real-time communication can be achieved using WebSockets technology, and PHP, as one of the most widely used development languages ​​in the Internet field, also provides corresponding WebSocket support. This article will introduce how to use PHP and WebSocket to achieve real-time communication, and provide specific code examples. 1. What is WebSocket? WebSocket is a single

How to implement an online speech recognition system using WebSocket and JavaScript How to implement an online speech recognition system using WebSocket and JavaScript Dec 17, 2023 pm 02:54 PM

How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

The combination of Java and WebSocket: how to achieve real-time video streaming The combination of Java and WebSocket: how to achieve real-time video streaming Dec 17, 2023 pm 05:50 PM

With the continuous development of Internet technology, real-time video streaming has become an important application in the Internet field. To achieve real-time video streaming, the key technologies include WebSocket and Java. This article will introduce how to use WebSocket and Java to implement real-time video streaming playback, and provide relevant code examples. 1. What is WebSocket? WebSocket is a protocol for full-duplex communication on a single TCP connection. It is used on the Web

Combination of golang WebSocket and JSON: realizing data transmission and parsing Combination of golang WebSocket and JSON: realizing data transmission and parsing Dec 17, 2023 pm 03:06 PM

The combination of golangWebSocket and JSON: realizing data transmission and parsing In modern Web development, real-time data transmission is becoming more and more important. WebSocket is a protocol used to achieve two-way communication. Unlike the traditional HTTP request-response model, WebSocket allows the server to actively push data to the client. JSON (JavaScriptObjectNotation) is a lightweight format for data exchange that is concise and easy to read.

WebSocket and JavaScript: key technologies for implementing real-time monitoring systems WebSocket and JavaScript: key technologies for implementing real-time monitoring systems Dec 17, 2023 pm 05:30 PM

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

PHP and WebSocket: Best practices for real-time data transfer PHP and WebSocket: Best practices for real-time data transfer Dec 18, 2023 pm 02:10 PM

PHP and WebSocket: Best Practice Methods for Real-Time Data Transfer Introduction: In web application development, real-time data transfer is a very important technical requirement. The traditional HTTP protocol is a request-response model protocol and cannot effectively achieve real-time data transmission. In order to meet the needs of real-time data transmission, the WebSocket protocol came into being. WebSocket is a full-duplex communication protocol that provides a way to communicate full-duplex over a single TCP connection. Compared to H

How to use Java and WebSocket to implement real-time stock quotation push How to use Java and WebSocket to implement real-time stock quotation push Dec 17, 2023 pm 09:15 PM

How to use Java and WebSocket to implement real-time stock quotation push Introduction: With the rapid development of the Internet, real-time stock quotation push has become one of the focuses of investors. The traditional stock market push method has problems such as high delay and slow refresh speed. For investors, the inability to obtain the latest stock market information in a timely manner may lead to errors in investment decisions. Real-time stock quotation push based on Java and WebSocket can effectively solve this problem, allowing investors to obtain the latest stock price information as soon as possible.

How does Java Websocket implement online whiteboard function? How does Java Websocket implement online whiteboard function? Dec 17, 2023 pm 10:58 PM

How does JavaWebsocket implement online whiteboard function? In the modern Internet era, people are paying more and more attention to the experience of real-time collaboration and interaction. Online whiteboard is a function implemented based on Websocket. It enables multiple users to collaborate in real-time to edit the same drawing board and complete operations such as drawing and annotation. It provides a convenient solution for online education, remote meetings, team collaboration and other scenarios. 1. Technical background WebSocket is a new protocol provided by HTML5. It implements

See all articles