douzhang8144 2017-02-12 16:28
浏览 759
已采纳

在不等待响应的情况下执行HTTP GET请求[关闭]

I have a PHP script where users send OTP as SMS. The SMS gateway I use takes around 5-8 seconds to respond. I cannot wait that long. I need to make the request and immediately send an HTML response to the user.

I used curl and it takes too long, and a short timeout drops the connection and makes the gateway unpredictable. I need a way to make the request, execute some routines and preferably have the option to verify the request.

  • 写回答

1条回答 默认 最新

  • dongqie2028 2017-02-12 20:51
    关注

    You use stream_socket_client(). Do your GET request then get the results later.

    Make Request with stream_socket_client()

        $host = 'www.example.com';
        $path = '/';
        $http = "GET $path HTTP/1.0
    Host: $host
    
    ";
        $stream = stream_socket_client("$host:80", $errno,$errstr, 120,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); 
        if ($stream) {
          $sockets[] = $stream;  // supports multiple sockets
          fwrite($stream, $http);
        }
        else { 
          $err .=  "$id Failed<br>
    ";
        }  
    

    Get Responses with stream_select()

    $timeout = 120;
    $buffer_size = 8192;
    while (count($sockets)) {
      $read = $sockets; 
      stream_select($read, $write = NULL, $except = NULL, $timeout);
      if (count($read)) {
        foreach ($read as $r) { 
          $id = array_search($r, $sockets); 
          $data = fread($r, $buffer_size); 
          if (strlen($data) == 0) {  // done
            fclose($r); 
            unset($sockets[$id]);
          } 
          else {
            $result[$id] .= $data; // append buffer to result
          }
        }
      }
      else { 
     //   echo 'Timeout: ' . date('h:i:s') . "
    
    
    ";
        break;
      }
    }
    

    UPDATE

    You can make a request at anytime, and get the response anytime after the request. When a socket is created the $sockets array's key is the $id.

    You do not have to have the while loop if you want to use some other control method. The buffer in the example is 8K. If the response is more than 8K it will take multiple reads.

    If you do not want to retrieve the response then just close the socket and do not use the $sockets array. You may or may not need a delay before the fclose(). It depends upon how the host responds to a dropped connection.

    $host = 'www.example.com';
    $path = '/?param=value';
    $http = "GET $path HTTP/1.0
    Host: $host
    
    ";
    $stream = stream_socket_client("$host:80", $errno,$errstr, 120,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); 
    
    if ($stream) {
      fwrite($stream, $http);
      fclose($stream); 
    
    }
    else { 
      $err .=  "$id Failed<br>
    ";
    }     
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 tensorrt 推理 yolov8框出现错误
  • ¥15 用hc 05,做蓝牙控制小车 小车只能说初始遥控方向影响,后续不能更改
  • ¥15 51单片机怎么把每次输入键值保存到数组作为我的确认键的判断条件呢
  • ¥45 easy photo不能使用,求帮助
  • ¥15 c语言字符串单词入门问题报错
  • ¥30 我现在是双非人工智能专业不知道要不要转到软件工程专业
  • ¥15 请问12脉波整流机组的外特性曲线具体是如何推导
  • ¥15 abaqus里的python算法
  • ¥100 如何在思科模拟器中进入CEF模式
  • ¥15 Simulink 仿真如何使用MATLAB function模块获取到仿真过程中某一仿真时刻输入到模块的函数的值?