Reverse AJAX PHP Multiple User Chat

2.6k Views Asked by At

Here is the situation. I have an admin panel(which multiple admins use at the same time) and employee panel(which multiple employees use at the same time). An admin can chat with multiple employees at the same time but an employee can only chat with admin. All the chats are saved in database(mysql) with their respective "from,to,msg,time" fields, using which both the sides match the messages according to their active chat sessions. Right now I am using a setInterval(function(){ $.ajax(...); },3000); and in return server returns all the messages to the admin yet only returns the specific messages of the requesting employee. But this is not a practical solution since it will, if its not right, overuse my server resources with too much database queries too. A lot of improvements are possible. Starting with passing the last message's time to the server which then only sends back the messages that arrived later than that time. Still the ajax is calling every 3 seconds and database queries stay the same too. Then I can make it a self calling function with a 30 seconds delay like the following example.

waitformsg(){
    $.ajax({ url: "server", success: function(data){
        // Do whatever I wish with the data...
    }, dataType: "json", complete: waitformsg, timeout: 30000 });
}

But even if I use this technique, how to wait on the server-side, rather what to wait for? Keeping in mind I also want to reduce the number of database queries yet the only thing I need is the bunch of messages received after the sent time value. Something like the following would do but still what to wait for ?

<?php

    if ( isset($_GET['update']) ){
         $time = $_GET['timestamp'];
         while (...do what here...){
        usleep(10000);
        clearstatcache();
         }
    }
    $response = array();    
    $response['msg'] = "get the message from the database";    
    $response['timestamp'] = time();    
    echo json_encode($response);    
    flush();
}
?>

Kindly help me with this situation. How to set a trigger for which I can loop in the server in an environment where multiple users will be chatting simultaneously.

I have implemented the polling technique and it looks good so far but I am still not very happy because of excessive database queries. I am still open to suggestions.

Following is the server code.

<?php
    require('database.class.php');
    $database = new database('****','****','****','****');

    if ( isset($_POST['update']) ){
        $lasttime = isset($_POST['timestamp']) ? $_POST['timestamp'] : 0;
        while (1){
            $msgs = $database->executeObjectList("SELECT * FROM tblchatdummy WHERE timestamp > $lasttime");
            if (!empty($msgs)){
                break;
            }
            sleep(2);
            clearstatcache();
        }
        echo json_encode($msgs);
        flush();
    }elseif ( isset($_POST['save']) ){
        $msg = isset($_POST['msg']) ? $_POST['msg'] : '';
        if ($msg != ''){
            $from = $_POST["from"];
            $to = $_POST["to"];
            $timestamp = time();
            $message = filter_var(trim($msg),FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
            $database->executeNonQuery("INSERT INTO tblchatdummy(msg_to, msg_from, msg, timestamp) VALUE('".$to."','".$from."','".$message."','".$timestamp."')");
            $response = array();
            $response['success'] = "1";
            $response['timestamp'] = $timestamp;
            echo json_encode($response);
            flush();
        }
    }
?>

Following is the client side. Its simple and effective which is why I like the client side.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  </head>
  <body>
<p>
    <input type="text" name="word" id="word" value="" />
    <input type="button" name="send" value="Send" id="mybutton"/>
</p>
<div id="content"></div>

<script type="text/javascript">
var lastime = 0;
$("#mybutton").click(function(){
    $.post("backend.php", {save:"1",from:"1",to:"5",msg:$("#word").val()}, function(data){
        $("#word").val("");
    }, "json");
});

(function update(){
    $.ajax({ type: "POST", url: "backend.php", data: {update:"1",timestamp:lastime}, success: function(data1){
        lastime = handleDATA(data1);
    }, dataType: "json", complete: update, timeout: 30000 });
})();

function handleDATA (data){
    for(i=0;i<data.length;i++){
        $("#content").append(data[i].msg+"</br>");
    }
    return data[data.length-1].timestamp;
}
</script>

</body>
</html>

Once again, I am still open to suggestions/advices.

0

There are 0 best solutions below