PHP实现web socket长链接流程详解

 更新时间:2023年03月25日 11:29:13   作者:深斗士  
这篇文章主要介绍了PHP实现web socket长链接流程,了解内部原理是为了帮助我们做扩展,同时也是验证了一个人的学习能力,如果你想让自己的职业道路更上一层楼,这些底层的东西你是必须要会的

简介

目前PHP实现web socket 都是使用框架集成来实现,比如hyperf,swoft,或者是安装swoole 扩展来实现websocket,那么有没有PHP本身就能够实现的呢,答案当然有,Let’s go.

函数介绍

服务端

stream_socket_server — Create an Internet or Unix domain server socket

可以帮我创建网络链接具柄,参数如下

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 //服务端
$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)) { //循环 等待链接
    fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");//成功链接输出以上内容 大致为: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);
}
?>

解释

上面的事例,只能在服务器之间调用,而且每次链接都会断开,一旦需要使用服务就需要不断的进行连接,不断的进行三次握手很浪费资源,那么能不能实现一个呢,No Code No BB.

JsDemo

// 创建websocket
ws = new WebSocket("ws://"+domain+"/"+port);
// 当socket连接打开时,输入用户名
ws.onopen = function(){}; //自定义 连接建立时处理操作,比如IM系统登陆信息操作
// 当有消息时根据消息类型显示不同信息
ws.onmessage = function(){};// 操作服务端发来的消息 
ws.onclose = function() {
  console.log("连接关闭,定时重连");
  connect();//重新连接
};
ws.onerror = function() {
  console.log("出现错误");
};

PHP实现三次握手

$socket = stream_socket_server('tcp://'.$ipServer.':'.$portNumber, $errno, $errstr);
while($conn = @stream_socket_accept($socket,$nbSecondsIdle))
{
            $message= fread($conn, 1024);
            send($conn,$message);
  					//@todo
  					//连接成功,有要保持连接,用来接收客户端发送过来的数据包 这里可以把这个连接$conn 保存在内存当中,通过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);//打印握手信息,然后发送给客户端,建立完整连接
    //socket_write($socket,$handshake_message);
    $len = @\fwrite($socket, $handshake_message);
    return 0;
}

到此这篇关于PHP实现web socket长链接流程详解的文章就介绍到这了,更多相关PHP web socket长链接内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • PHP设计模式之原型设计模式原理与用法分析

    PHP设计模式之原型设计模式原理与用法分析

    这篇文章主要介绍了PHP设计模式之原型设计模式,简单描述了原型设计模式的概念、原理并结合实例形式分析了php原型设计模式的定义与使用方法,需要的朋友可以参考下
    2018-04-04
  • 探讨捕获php错误信息方法的详解

    探讨捕获php错误信息方法的详解

    本篇文章是对捕获php错误信息的方法进行了详细的分析介绍,需要 的朋友参考下
    2013-06-06
  • 基于PHP实现原生增删改查的示例代码

    基于PHP实现原生增删改查的示例代码

    这篇文章主要介绍了如何利用php写个原生增删改查功能,文中的示例代码讲解,对我们学习PHP有一定帮助,感兴趣的小伙伴可以了解一下
    2022-04-04
  • PHP的instanceof详解及使用方法介绍

    PHP的instanceof详解及使用方法介绍

    php的instanceof是什么意思?instanceof由两个单词组成,instance和of,instance表示实例的意思,从字面上就可以理解这是实例引用的意思。instanceof 运算符是 PHP 5 引进的。在此之前用 is_a(),但是 is_a() 已经过时了,最好用 instanceof。
    2023-05-05
  • php5.5使用PHPMailer-5.2发送邮件的完整步骤

    php5.5使用PHPMailer-5.2发送邮件的完整步骤

    PHPMailer已经更新了很多版本了,本教程只针对老版本。下面这篇文章主要给大家介绍了关于php5.5使用PHPMailer-5.2发送邮件的完整步骤,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-10-10
  • php用数组返回无限分类的列表数据的代码

    php用数组返回无限分类的列表数据的代码

    php自定义函数之用数组返回无限分类的列表数据,这样的实现可以提高执行的效率不要每次都从数据库读取数据。
    2010-08-08
  • PHP中使用CURL伪造来路抓取页面或文件

    PHP中使用CURL伪造来路抓取页面或文件

    这个是用 PHP 伪造来路, 抓取文件或页面的代码, 挺简单的.
    2011-05-05
  • Apache服务器无法使用的解决方法

    Apache服务器无法使用的解决方法

    本篇文章介绍了Apache服务器在无法使用时候的一些解决方法。需要的朋友参考下
    2013-05-05
  • PHP命名空间用法实例分析

    PHP命名空间用法实例分析

    这篇文章主要介绍了PHP命名空间用法,结合实例形式分析了php命名空间的定义与简单使用操作技巧,需要的朋友可以参考下
    2019-09-09
  • PHP实现的Redis操作通用类示例

    PHP实现的Redis操作通用类示例

    这篇文章主要介绍了PHP实现的Redis操作通用类,结合实例形式分析了php实现的redis连接、队列、集合、hash表、事务等相关操作封装技巧,需要的朋友可以参考下
    2018-06-06

最新评论