Rumah pembangunan bahagian belakang tutorial php WebSocket中的长连接以及超时问题的解决问题(代码)

WebSocket中的长连接以及超时问题的解决问题(代码)

Jan 12, 2019 am 10:01 AM
websocket

本篇文章给大家带来的内容是关于WebSocket中的长连接以及超时问题的解决问题(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

<?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();
Salin selepas log masuk


网上看到很多说会断开链接,设置心跳包也没有用

我这里直接配置了下 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 = &#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>
Salin selepas log masuk


 

Atas ialah kandungan terperinci WebSocket中的长连接以及超时问题的解决问题(代码). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Dec 17, 2023 pm 02:54 PM

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

Bagaimana untuk mencapai komunikasi masa nyata menggunakan PHP dan WebSocket Bagaimana untuk mencapai komunikasi masa nyata menggunakan PHP dan WebSocket Dec 17, 2023 pm 10:24 PM

Dengan perkembangan teknologi Internet yang berterusan, komunikasi masa nyata telah menjadi bahagian yang amat diperlukan dalam kehidupan seharian. Komunikasi masa nyata yang cekap, kependaman rendah boleh dicapai menggunakan teknologi WebSockets, dan PHP, sebagai salah satu bahasa pembangunan yang paling banyak digunakan dalam bidang Internet, juga menyediakan sokongan WebSocket yang sepadan. Artikel ini akan memperkenalkan cara menggunakan PHP dan WebSocket untuk mencapai komunikasi masa nyata, dan menyediakan contoh kod khusus. 1. Apakah itu WebSocket?

Gabungan Java dan WebSocket: bagaimana untuk mencapai penstriman video masa nyata Gabungan Java dan WebSocket: bagaimana untuk mencapai penstriman video masa nyata Dec 17, 2023 pm 05:50 PM

Dengan perkembangan berterusan teknologi Internet, penstriman video masa nyata telah menjadi aplikasi penting dalam bidang Internet. Untuk mencapai penstriman video masa nyata, teknologi utama termasuk WebSocket dan Java. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan Java untuk melaksanakan main balik penstriman video masa nyata dan memberikan contoh kod yang berkaitan. 1. Apakah itu WebSocket? WebSocket ialah protokol untuk komunikasi dupleks penuh pada sambungan TCP tunggal

Gabungan golang WebSocket dan JSON: merealisasikan penghantaran dan penghuraian data Gabungan golang WebSocket dan JSON: merealisasikan penghantaran dan penghuraian data Dec 17, 2023 pm 03:06 PM

Gabungan golangWebSocket dan JSON: merealisasikan penghantaran dan penghuraian data Dalam pembangunan Web moden, penghantaran data masa nyata menjadi semakin penting. WebSocket ialah protokol yang digunakan untuk mencapai komunikasi dua hala Tidak seperti model respons permintaan HTTP tradisional, WebSocket membenarkan pelayan untuk menolak data secara aktif kepada klien. JSON (JavaScriptObjectNotation) ialah format ringan untuk pertukaran data yang ringkas dan mudah dibaca.

PHP dan WebSocket: Amalan terbaik untuk pemindahan data masa nyata PHP dan WebSocket: Amalan terbaik untuk pemindahan data masa nyata Dec 18, 2023 pm 02:10 PM

PHP dan WebSocket: Kaedah Amalan Terbaik untuk Pemindahan Data Masa Nyata Pengenalan: Dalam pembangunan aplikasi web, pemindahan data masa nyata merupakan keperluan teknikal yang sangat penting. Protokol HTTP tradisional ialah protokol model tindak balas permintaan dan tidak boleh mencapai penghantaran data masa nyata dengan berkesan. Untuk memenuhi keperluan penghantaran data masa nyata, protokol WebSocket telah wujud. WebSocket ialah protokol komunikasi dupleks penuh yang menyediakan cara untuk berkomunikasi dupleks penuh melalui sambungan TCP tunggal. Berbanding dengan H

WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata Dec 17, 2023 pm 05:30 PM

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Cara menggunakan Java dan WebSocket untuk melaksanakan push sebut harga saham masa nyata Cara menggunakan Java dan WebSocket untuk melaksanakan push sebut harga saham masa nyata Dec 17, 2023 pm 09:15 PM

Cara menggunakan Java dan WebSocket untuk melaksanakan push sebut harga saham masa nyata Pengenalan: Dengan perkembangan pesat Internet, push sebut harga saham masa nyata telah menjadi salah satu tumpuan pelabur. Kaedah tolakan pasaran saham tradisional mempunyai masalah seperti kelewatan yang tinggi dan kelajuan penyegaran yang perlahan Bagi pelabur, ketidakupayaan untuk mendapatkan maklumat pasaran saham terkini tepat pada masanya boleh menyebabkan kesilapan dalam keputusan pelaburan. Tolakan sebut harga saham masa nyata berdasarkan Java dan WebSocket boleh menyelesaikan masalah ini dengan berkesan, membolehkan pelabur mendapatkan maklumat harga saham terkini secepat mungkin.

Bagaimanakah Java Websocket melaksanakan fungsi papan putih dalam talian? Bagaimanakah Java Websocket melaksanakan fungsi papan putih dalam talian? Dec 17, 2023 pm 10:58 PM

Bagaimanakah JavaWebsocket melaksanakan fungsi papan putih dalam talian? Dalam era Internet moden, orang ramai memberi lebih banyak perhatian kepada pengalaman kerjasama dan interaksi masa nyata. Papan putih dalam talian ialah fungsi yang dilaksanakan berdasarkan Websocket Ia membolehkan berbilang pengguna bekerjasama dalam masa nyata untuk mengedit papan lukisan yang sama dan menyelesaikan operasi seperti lukisan dan anotasi. Ia menyediakan penyelesaian yang mudah untuk pendidikan dalam talian, mesyuarat jarak jauh, kerjasama pasukan dan senario lain. 1. Latar belakang teknikal WebSocket ialah protokol baharu yang disediakan oleh HTML5

See all articles