各类知识收集,PHP技术分享与解决方案各类知识收集,PHP技术分享与解决方案各类知识收集,PHP技术分享与解决方案

Str Tom,为分享PHP技术和解决方案,贡献一份自己的力量!
QQ:420220301 微信/手机:150-3210-7690
当前位置:首页 > CMS教程 > PHP

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

管理员 2023-09-05
PHP
126

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

内容导读

收集整理的这篇技术教程文章主要介绍了WebSocket中的长连接以及超时问题的解决问题(代码),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含8011字,纯文字阅读大概需要12分钟

内容图文

本篇文章给大家带来的内容是关于WebSocket中的长连接以及超时问题的解决问题(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
<?phpset_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("/rn/", $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 Handshakern" .            "Upgrade: websocketrn" .            "Connection: Upgradern" .            "WebSocket-Origin: $this->addressrn" .            "WebSocket-Location: ws://$this->address:$this->port/服务器地址rn".            "Sec-WebSocket-Accept:$secAcceptrnrn";        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中的长连接以及超时问题的解决问题(代码)的详细内容,更多请关注Gxl网其它相关文章!

内容总结

以上是为您收集整理的WebSocket中的长连接以及超时问题的解决问题(代码)全部内容,希望文章能够帮你解决WebSocket中的长连接以及超时问题的解决问题(代码)所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。

内容备注

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。


希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 lecms, classcms, fastadmin, pbootcms, phpcms, eyoucms, yzmcms, PHP, xunruicms, jizhicms, dedecms, wordpress, hkcms, yzncms, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。

扫码关注

qrcode

QQ交谈

回顶部