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

作者:深斗士 时间:2023-05-27 23:44:39 

简介

目前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;
}

来源:https://blog.csdn.net/qq_22635549/article/details/129723549

标签:PHP,web,socket,长连接
0
投稿

猜你喜欢

  • asp和php页面全面封杀WVS扫描器的代码

    2011-02-28 10:43:00
  • IE7异常CSS 导致内存破坏漏洞

    2009-11-30 12:52:00
  • 如何在事件代理中正确使用 focus 和 blur 事件

    2010-01-30 12:51:00
  • 【推荐】汉字转为拼音的asp函数

    2007-08-17 11:11:00
  • IE7的web标准之道 Ⅰ

    2008-08-13 12:42:00
  • WinHttp.WinHttpRequest--XmlHttp获取跳转页面的功能

    2010-03-22 14:34:00
  • SQL Server数据库实用小技巧集合

    2008-11-25 11:35:00
  • AJAX快速入门之HTTP协议基础

    2008-01-16 19:04:00
  • 一个取图片尺寸的类,支持jpg,gif,png

    2007-10-18 10:25:00
  • sql server对字段的添加修改删除、以及字段的说明

    2012-01-05 18:50:52
  • 什么是响应式Web设计?怎样进行?

    2011-11-21 17:00:40
  • Google谷歌农历鼠年春节的变化

    2008-02-11 17:07:00
  • SQL Server 数据库故障修复顶级技巧之一

    2010-05-01 18:49:00
  • asp内置对象Application详解

    2007-09-19 12:08:00
  • Varchar与char的区别

    2008-02-28 12:44:00
  • Oracle字符集修改查看方法

    2009-11-05 21:45:00
  • 网址站的2.0玩法

    2010-03-15 12:25:00
  • Mysql Innodb 引擎优化

    2010-10-25 20:01:00
  • 不是原型继承那么简单!prototype的深度探索

    2008-03-07 12:42:00
  • IIRF(Ionic's Isapi Rewrite Filt er)入门,在IIS上重写Url

    2007-09-23 12:16:00
  • asp之家 网络编程 m.aspxhome.com