Daria
Daria

Reputation: 861

Asynchronous API and callback

I have to use one asynchronous service. Everything I can do is send data to this service (I'm doing it with PHP and CURL) and send data to some url from this service. How can I react/wait for a response from this service? Now I have two pages: first is sending data to service and the second takes a response from this service and inserts it to database. On a first page I'm checking some table while there isn't the response. But selecting from database few times per second is bad idea. But what I need to have: Send data from one page and get the response at the same page. I guess I can use some Ajax and make the async service sending data to the same page and wait for the response on this page.

I guess I wrote very hard because I can't fully explain what I need, so feel free to correct me.

Upvotes: 0

Views: 74

Answers (2)

Steve
Steve

Reputation: 20469

Your easiest option is going to be ajax polling - send the request to the webservice, then poll every x seconds. The response handler (the script called by the webservice when it completes) need to save the data somewhere, eg database or session, and the poll script will check for this data.

Although this will add a little to server load, if you set the polling interval high enough it should be fine

session_start();
if(isset($_GET['sendrequest'])){

    WebService:sendRequest(['callback_url'=>'thispage?receiveresponse=1'])
    $_SESSION['response']=false;
    die();
}elseif(isset($_GET['receiveresponse'])){

    $response = WebService:receive();
    $_SESSION['response'] = $response;
    die();

}elseif(isset($_GET['checkresponse'])){

    $data=[];
    if($_SESSION['response']){
        $data['success']=true;
        $data['response']=$_SESSION['response'];
    }else{
        $data['success']=false;
    }

    header('Content-Type: application/json');
    die(json_encode($data);
}
<html>
  <head>....</head>
  <body>

  <a id="send" href="#">Send Request</a>
  <div id="response"></div>

  <script>
       var poll;
       $('#send').click(function(ev){
           ev.preventDefault();
           $post('?sendrequest=1', {...}, function(){
                poll = setInterval(function(){
                    $get('?checkresponse=1', function(response){
                        if(response.success){
                            clearInterval(poll);
                            $('#response').html(response.response);
                        }
                    });
                }), 3000);
           });
        });
  </script>
  </body>
</html>

Upvotes: 1

hindmost
hindmost

Reputation: 7195

As @Steve noted, PHP has no concept of asynchronousity. However there is a hack which allows to implement something similar to long-polling in PHP. The main point is to use a file ready to read in Javascript, i.e. JSON.

Here is a general flow:

  1. Your single web page does AJAX request to your php script which send appropriate request to the external service and immediately return some response (e.g. empty) to the web page.
  2. The web page starts to repeatedly request server for the same static JSON file (by doing AJAX requests) until it appears (created by callback script).
  3. The external service passes response to your callback script which save the response into the JSON file.
  4. The web page get the response from the JSON file and outputs it.

Upvotes: 1

Related Questions