当前位置:首页 > PHP教程 > php高级应用 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2023-07-03 19:09:58 浏览: 评论:0 

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

函数介绍

服务端

stream_socket_server — Create an Internet or Unix domain server socket

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

  1. stream_socket_server( 
  2. string $address
  3. int &$error_code = null, 
  4. string &$error_message = null, 
  5. int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, 
  6. ?resource $context = null 
  7. ): resource|false 

客户端

stream_socket_client — Open Internet or Unix domain socket connection

连接句柄

  1. stream_socket_client( 
  2. string $address
  3. int &$error_code = null, 
  4. string &$error_message = null, 
  5. ?float $timeout = null, 
  6. int $flags = STREAM_CLIENT_CONNECT, 
  7. ?resource $context = null 
  8. ): resource|false 

简单运用

  1. <?php //服务端 
  2. $socket = stream_socket_server("tcp://0.0.0.0:8000"$errno$errstr); 
  3. if (!$socket) { 
  4.   echo "$errstr ($errno)<br />\n"
  5. else { 
  6.   while ($conn = stream_socket_accept($socket)) { //循环 等待链接 
  7.     fwrite($conn'The local time is ' . date('n/j/Y g:i a') . "\n");//成功链接输出以上内容 大致为:The local time is 3/22/2023 11:13 am 
  8.     fclose($conn); //断开连接 
  9.   } 
  10.   fclose($socket); //断开socket 
  11. ?> 
  12. <?php //客户端 
  13. $fp = stream_socket_client("tcp://0.0.0.0:8000"$errno$errstr, 30); 
  14. if (!$fp) { 
  15.     echo "$errstr ($errno)<br />\n"
  16. else { 
  17.     fwrite($fp"GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n"); 
  18.     while (!feof($fp)) { 
  19.         echo fgets($fp, 1024); 
  20.     } 
  21.     fclose($fp); 
  22. ?> 

解释

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

JsDemo

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

PHP实现三次握手

  1. $socket = stream_socket_server('tcp://'.$ipServer.':'.$portNumber$errno$errstr); 
  2. while($conn = @stream_socket_accept($socket,$nbSecondsIdle)) 
  3.             $messagefread($conn, 1024); 
  4.             send($conn,$message); 
  5.                     //@todo 
  6.                     //连接成功,有要保持连接,用来接收客户端发送过来的数据包 这里可以把这个连接$conn 保存在内存当中,通过Select or Swoole 事件去loop 
  7.             fputs ($conn"OK\n"); 
  8. function send($socket,$buffer){ 
  9.     $Sec_WebSocket_Key = ''
  10.     if (\preg_match("/Sec-WebSocket-Key: *(.*?)\r\n/i"$buffer$match)) { 
  11.         $Sec_WebSocket_Key = $match[1]; 
  12.     } 
  13.     $new_key = \base64_encode(\sha1($Sec_WebSocket_Key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)); 
  14.     $handshake_message = "HTTP/1.1 101 Switching Protocols\r\n" 
  15.         ."Upgrade: websocket\r\n" 
  16.         ."Sec-WebSocket-Version: 13\r\n" 
  17.         ."Connection: Upgrade\r\n" 
  18.         ."Sec-WebSocket-Accept: " . $new_key . "\r\n"
  19.     $handshake_message .= "\r\n"
  20.     var_dump($handshake_message);//打印握手信息,然后发送给客户端,建立完整连接 
  21.     //socket_write($socket,$handshake_message); 
  22.     $len = @\fwrite($socket$handshake_message); 
  23.     return 0; 
  24. }

Tags: PHP长链接 socket长链接

分享到: