Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pushing data to user browser from server

Tags:

I want to push data from server to browser. I am already aware of php function ob_flush() which sends output buffer. I need help with a bit of logic. I am using Facebook real time API so i want to push data to user everytime Facebook visits my website.

Here is my code that i am trying to push data to browser but its not working.

<?php
header('Access-Control-Allow-Origin: *');
header('Content-Type: text/event-stream');
ini_set("log_errors", 1);
ini_set("error_log", "php-error.log");
error_log( "LOGS STARTS FROM HERE" );
if(isset($_GET['hub_challenge'])){
    echo $_GET['hub_challenge'];    
}
if($_SERVER['REQUEST_METHOD'] == "POST"){
    $updates = json_decode(file_get_contents("php://input"), true); 
    // Replace with your own code here to handle the update 
    // Note the request must complete within 15 seconds.
    // Otherwise Facebook server will consider it a timeout and 
    // resend the push notification again.
    print_r($updates);
    ob_flush();
    flush();
    //file_put_contents('fb.log', print_r($updates,true), FILE_APPEND);     
    //error_log('updates = ' . print_r($updates, true));              
}
?>
like image 624
Skyyy Avatar asked Jun 28 '15 17:06

Skyyy


2 Answers

As @som suggested, you can simply use requests with an interval between them, you don't need to use sockets.

But the thing is, you are trying to receive data from the API and pass it right to the browser, all at once. It's best if you separate those two steps.

In the script that receives the data from Facebook, store that data in a database or somewhere else:

if($_SERVER['REQUEST_METHOD'] == "POST"){
    $updates = json_decode(file_get_contents("php://input"), true); 

    insertDataToDatabase($updates); // you'll have to implement this.
}

Then setup a monitoring page:

monitor.php

<script>
lastId = 0;

$(document).ready(function() {
    getNewDataAtInterval();
});

function getNewDataAtInterval() {
    $.ajax({
        dataType: "json",
        url: "getData.php",
        data: {lastId: lastId}
    }).done(function(data) {
        for(i=0; i<data.messages.length; i++) {
            $("#messages").append("<p>" + data.messages[i]['id'] + ": " + data.messages[i]['message'] + "</p>");
            if (data.messages[i]['id'] > lastId) lastId = data.messages[i]['id'];
        }

        setTimeout(getNewDataAtInterval, 10000);
    }).fail(function( jqXHR, textStatus ) {
        alert( "Request failed: " + jqXHR.responseText );
    });
}
</script>

<div id="messages"></div>

At last, create a server-side script to return a JSON with the new messages loaded from the database.

getData.php

$lastId = $_GET['lastId'];
$newMessages = getUpdatesFromDatabase($lastId);

exit(json_encode(array("messages"=>$newMessages)));

function getUpdatesFromDatabase($lastId) {
    // I'm using this array just as an example, so you can see it working.
    $myData = array(
        array("id"=>1,"message"=>"Hi"),
        array("id"=>2,"message"=>"Hello"),
        array("id"=>3,"message"=>"How are you?"),
        array("id"=>4,"message"=>"I'm fine, thanks")
    );

    $newMessages = array();
    foreach($myData as $item) {
        if ($item["id"] > $lastId) {
            $newMessages[] = $item;
            $newLastId = $item["id"];
        }
    }

    return $newMessages;
}
like image 172
Marcos Dimitrio Avatar answered Oct 05 '22 01:10

Marcos Dimitrio


Use of Comet or Prototype will be best practice here. Ajax will increase server load. It will polling the server frequently. Here is some necessary information about using comet.

Here is the example of how to implement comet with php to send real-time data.

like image 33
Pratik Soni Avatar answered Oct 05 '22 02:10

Pratik Soni