I want to achieve a pseudo real time chat app inside a Codeigniter framework using long polling. I know it's not the best option (I could try with HTML5 Websocket), but I'm on a cPanel shared account so I don't have any privileges on installing anything
So, let's get back to the issue itself.
Basically, I use a .js file similar to the one below:
//get server time
var time;
$.ajax( {
url: JS_BASE_URL + 'admin/users/get_time',
success: function( dataResponse ) {
time = dataResponse;
},
type: 'GET'
} );
//long polling AJAX
function getNewMsgs() {
$.ajax( {
url: JS_BASE_URL + 'admin/users/get_new_msgs',
type: 'POST',
// send the time
data: { time: time, sender_id: sender_id },
dataType: 'json',
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
success: function( dataResponse ) {
// update the time
time = dataResponse.time;
// show the new messages
dataResponse.msgs.forEach( function( msg ) {
preparePost('in', (msg.date_sent), msg.sender_id, 'avatar3', msg.message);
} );
// repeat
setTimeout( getNewMsgs(), 1000 );
},
error: function (XMLHttpRequest, textStatus, errorThrown){
setTimeout( getNewMsgs(), 1000 );
}
} );
}
getNewMsgs(); // this one is on the document ready
The php get_new_msgs function in Users controller:
function get_new_msgs() {
echo json_encode( array(
'msgs' => $this->aauth->start_polling($this->aauth->get_user()->id),
// response again the server time to update the "js time variable"
'time' => time()
) );
die();
}
And the model function start_polling:
function start_polling($receiver_id) {
// get the time
$time = $this->CI->input->post( 'time' );
$sender_id = $this->CI->input->post( 'sender_id' );
// some crappy validation
if( !is_numeric( $time ) ) {
return array();
}
$time = date('Y-m-d G:i:s',$time);
// -> 2010-10-01
//$time = $time['year'] + '-' + $time['mon'] + '-' + $time['mday'];
while( true ) {
$where = 'date_sent >= "' . $time . '" AND ((receiver_id=' . $receiver_id . ' AND pm_deleted_receiver IS NULL AND sender_id=' . $sender_id . ' AND pm_deleted_sender IS NULL) OR (receiver_id=' . $sender_id . ' AND pm_deleted_receiver IS NULL AND sender_id=' . $receiver_id . ' AND pm_deleted_sender IS NULL))';
$query = $this->aauth_db->where($where);
$query = $this->aauth_db->order_by('id','ASC');
$query = $this->aauth_db->get( $this->config_vars['pms']);
//die($this->aauth_db->last_query());
if( $query->num_rows() > 0 ) {
$result = $query->result();
if ($this->config_vars['pm_encryption']){
$this->CI->load->library('encrypt');
foreach ($result as $k => $r)
{
$result[$k]->title = $this->CI->encrypt->decode($r->title);
$result[$k]->message = $this->CI->encrypt->decode($r->message);
}
}
echo json_encode($result);
die();
} else {
sleep( 1 );
continue;
}
}
}
Now, the issue is that whenever I run the page with the chat, a request is loaded and waiting for a response from the server. But, no other requests will finish.. it seems that the other requests sent after the long polling are waiting for that first one to finish.. Even if I stop the script, the page will load very slow..
Any idea on what I'm missing?
Thank you in advance!
Related
I have a very annoying bug. My AJAX queries are failing anywhere up to 20-30 times with 500 GET and POST server errors, but then all of a sudden they work.
It seems to be completely random, as sometimes I will load the page and it will work fine for a full day of usage, but then the next day it will fail and I have to catch and retry it up to 30 times to get it to work.
AJAX
function getData(){
//Get Data and build contributions Table
$.ajax({
url: 'assets/processes/dash/support/get-data.php', // URL of php command
tryCount : 0,
retryLimit : 3,
type: 'POST', //TYPE
data: {'id': id}, //Variables in JSON FORMAT
success: function(results) { //SUCCESSFUL REQUEST FUNCTION
var result = $.parseJSON(results);
console.log(result);
},
error : function(xhr, textStatus, errorThrown ) {
if (textStatus == 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) {
$.ajax(this);
return;
}
return;
}
if (xhr.status == 500) {
$.ajax(this);
return;
} else {
//handle error
}
}
}); // end ajax call
PHP
<?php
include "../../../includes/database.php";
$totalOpen = $db->pdo_query_assoc("xdGetTotalUnresolvedTickets
1,0,0,0,0,0");
$totalWaitState = $db->pdo_query_assoc("xdGetWaitState 1,0,0,0,0,0");
$nonWaitState = $totalOpen['xdGetTotalUnresolvedTickets'] -
$totalWaitState['xsGetWaitState'];
$getStaff = $db->query("SELECT * FROM user WHERE role = 'Technical
Support'");
$getStaffArray = array();
foreach($getStaff as $key => $value){
$sqlUsername = $value['sqlName'];
$pdo_today = $db->pdo_query_assoc("xsGetTotalResolvedTicketsToday
'$sqlUsername'");
$start = date('Y-m-d ', strtotime('-7 days'));
$end = date('Y-m-d ', strtotime('+1 days'));
$pdo_last_week = $db->pdo_query_assoc("xsGetTotalResolvedTicketsToday
'$sqlUsername','$start','$end'");
$getCompletionRate = $db->pdo_query_assoc('xStaffTicketCompletionRate
"'.$sqlUsername.'"');
$getWeeklyRate = $db->pdo_query_assoc('xLastSevenPreviousSeven
"'.$sqlUsername.'"');
$getStaffArray[$key]['staffName'] = $value['user'];
$getStaffArray[$key]['staffFullName'] = $value['name'];
$getStaffArray[$key]['colourScheme'] = $value['colourScheme'];
$getStaffArray[$key]['today'] =
$pdo_today['xsGetTotalResolvedTicketsToday'];
$getStaffArray[$key]['thisWeek'] =
$pdo_last_week['xsGetTotalResolvedTicketsToday'];
$getStaffArray[$key]['completionRate'] = $getCompletionRate['Level'];
$getStaffArray[$key]['thisTimeLastWeek'] =
round($getWeeklyRate['Percentage'],1);
$getStaffArray[$key]['weeklyRateLevel'] = $getWeeklyRate['Level'];
$getStaffArray[$key]['weeklyPrevious7'] = $getWeeklyRate['Previous 7
Days'];
$getStaffArray[$key]['weeklyEarlier7'] = $getWeeklyRate['Earlier 7
Days'];
}
$tickets = array('totalCurrent' => $totalOpen, 'totalWaitState' =>
$totalWaitState, 'totalNoneWaitState' => $nonWaitState);
$allData = array('totalTickets' => $tickets, 'staff' => $getStaffArray);
echo json_encode($allData, JSON_FORCE_OBJECT);
?>
I know at the moment the trycount doesnt work properly, as instead of trying 3 times it tries unlimited amount until it works. Any one have any ideas as to why this could be happening?
They always fail on the php file, like the query cant be executed.
ERROR
GET http://mysite/get-events.php 500 (Internal Server Error)
jquery.min.js:4
I am trying to make a facebook webpage messenger like app and I use AJAX in client side and php on my server side.
My AJAX code:
function longPoll(timestamp)
{
var queryString = {'timestamp' : timestamp};
var shouldDelay = false;
$.ajax(
{
type: 'GET',
async: true,
url: 'pollMsg.php',
data: queryString,
timeout: 5000,
cache: false
}
).done(function(data){
var array = jQuery.parseJSON(data);
for (var i = 0; i < array.length; i++) {
$('#msgTable > tbody:last-child').append('<tr><td><b>' + array[i].sender + '</b><br/>' + array[i].timestamp + '</td><td><b>' + array[i].title + '</b><br/>' + array[i].content + '</td></tr>');
}
longPoll(obj.timestamp);
}).fail(function(jqXHR, textStatus, errorThrown) {
//shouldDelay = textStatus !== "timeout";
}).always(function() {
var delay = shouldDelay ? 5000: 0;
if (shouldDelay) {
shouldDelay = false;
window.setTimeout(longPoll, delay);
}
});
}
// initialize jQuery
$(function() {
longPoll();
});
My PHP code:
//set php runtime to unlimited
set_time_limit(10);
while (true) {
$last_ajax_call = isset($_GET['timestamp']) ? (int)$_GET['timestamp'] : '1970-01-01 00:00:00';
$sql = "select * from post where (receiver = ? or sender = ?) and postat > str_to_date(?, '%Y/%m/%d %H:%i:%s')";
$stmt = $conn->prepare($sql);
$stmt->bind_param("sss", $username, $username, $last_ajax_call);
$result = $stmt->execute();
$rows = $stmt->get_result()->fetch_all();
if (count($rows) > 0) {
$result = array();
foreach ($rows as $row) {
$data = array (
'sender' => $row[3],
'timestamp' => $row[5],
'title' => $row[1],
'content' => $row[2]
);
array_push($result, $data);
}
$json = json_encode($result);
echo $json;
break;
} else {
sleep( 1 );
continue;
}
}
I found that if I once click on the page with the AJAX code, when I change to other page in the same webserver, I will get a nginx error (as I use nginx).
What is the problem in my code? I have found some example of long polling and it gives me similar code. Thank you.
When I restart php-fpm, everything is okay, which means that I have generated so many request so that the server cannot handle.
I've created an Arduino project wich sends the coordinates to an URL. The URL does some ajax calls. In the browser it works fine, but when I'm trying it with the Arduino it doesn't work. So I tried to do the same thing with an iOS app, but I got the same problem. This is the code on the page that the Arduino and iOS app request.
var directionsService = new google.maps.DirectionsService();
var base_url = window.location;
var received_data = <?php echo json_encode($received_data); ?>;
$.ajax({
url: 'http://gps-tracker.domain.nl/_api/handler.php',
data: { action: 'post', device_id: received_data['device_id']},
type: 'GET',
dataType:"jsonp",
jsonp:"callback",
success: function (response){
var error = [];
var total = response.length;
for (var type in response) {
if(response[type].types == 'area'){
var x = checkInsideCircle(response[type].longitude, response[type].latitude, received_data['longitude'], received_data['latitude'], response[type].reach / 1000);
if(x == false){
// Outside
error.push(true);
}else{
// Inside
error.push(false);
}
}else if(response[type].types == 'route'){
// Check route
checkOnRoute(response[type].start_latitude, response[type].start_longitude, response[type].end_latitude, response[type].end_longitude, response[type].type, response[type]['reach'], type, function(result) {
error.push(result);
if(error.length == total){
if(error.indexOf(false) >= 0){
// Device is inside route or area
outside = false;
}else{
// Send data to database
$.ajax({
url: 'http://gps-tracker.domain.nl/_api/handler.php',
data: { action: 'post', device_id: received_data['device_id'], longitude: received_data['longitude'], latitude: received_data['latitude']},
type: 'GET',
dataType: 'json',
success: function (response){
console.log('good');
},error: function(jq,status,message) {
alert('A jQuery error has occurred. Status: ' + status + ' - Message: ' + message);
}
});
}
}
});
}
}
},error: function(jq,status,message) {
alert('A jQuery error has occurred. Status: ' + status + ' - Message: ' + message);
}
});
Here is the code from the handler.php file, that the ajax request requests.
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : false;
// Switch actions
switch($action) {
case 'get':
$callback ='callback';
if(isset($_GET['callback'])){
$callback = $_GET['callback'];
}
$routes = ORM::for_table('gps_tracker_route')
->inner_join('gps_tracker_device', array('gps_tracker_device.device_id', '=', 'gps_tracker_route.device_id'))
->where('gps_tracker_route.device_id', $_GET['device_id'])
->where('gps_tracker_device.device_id', $_GET['device_id']);
if($routes = $routes->find_many()){
foreach($routes as $k=>$v){
$v = $v->as_array();
if($v['status'] == 'on' or strtotime(date('Y-m-d H:i:s')) > strtotime($v['start_time']) and strtotime(date('Y-m-d H:i:s')) < strtotime($v['end_time'])){
$response1[$k] = $v;
$response1[$k]['types'] = 'route';
}
}
}
$area = ORM::for_table('gps_tracker_area')
->inner_join('gps_tracker_device', array('gps_tracker_device.device_id', '=', 'gps_tracker_area.device_id'))
->where('gps_tracker_area.device_id', $_GET['device_id'])
->where('gps_tracker_device.device_id', $_GET['device_id']);
if($area = $area->find_many()){
foreach($area as $k=>$v){
$v = $v->as_array();
if($v['status'] == 'on' or strtotime(date('Y-m-d H:i:s')) > strtotime($v['start_time']) and strtotime(date('Y-m-d H:i:s')) < strtotime($v['end_time'])){
$response2[$k] = $v;
$response2[$k]['types'] = 'area';
}
}
}
if(isset($response1) and isset($response2)){
$response = array_merge($response1, $response2);
}elseif(isset($response1)){
$response = $response1;
}else{
$response = $response2;
}
if ( isset($response) ) {
if ( is_array($response) ) {
if (function_exists('json_encode')) {
header('Content-Type: application/json');
echo $callback.'(' . json_encode($response) . ')';
} else {
include( ABSOLUTE_PATH . '/classes/json.class.php');
$json = new Services_JSON();
echo $json->encode($response);
}
} else {
echo $response;
}
exit(0);
}else{
exit();
}
break;
case 'post':
$_GET['timestamp'] = date("Y-m-d H:i:s");
$record = ORM::for_table('gps_tracker_device_logging')->create($_GET);
$record->save();
$item = ORM::for_table('gps_tracker_device_logging')
->where('id', $record->id);
if($item = $item->find_one()){
$item = $item->as_array();
echo json_encode($item);
}
break;
default:
die('invalid call');
}
Can someone help me?
EDIT
I think it is something with Javascript. I don't know if it's possible to use javascript when a device, like Arduino, makes a http request to a server. Someone know?
I think that it's because you need a Web Browser that supports JavaScript.
I don't work with Arduino, but from what I know it does not have a "real" Web Browser - it can only pull/download data but can't execute the JS part.
For JS to work you need something to run it. That is why it works in a the browser.
The ajax call successfully update the record but doesn't return the string of echo. This script was working before but might be because of some upgrade it stops working. It is working fine on my local system but when I move it to bluehost server then it does not work.
Here is my Ajax call:
// call to ajax script to update site
function autopost_update_site() {
// get base directory url
var baseDir = jQuery('#baseDir').val();
var id = jQuery('#site_id').val();
var site_name = jQuery('#site_name').val();
var site_url = jQuery('#site_url').val();
var is_active;
if ( jQuery('#active_radio').is(':checked') ){
is_active = '1';
} else {
is_active = '0';
}
var username = jQuery('#login_username').val();
var login_pass = jQuery('#login_pass').val();
// call to ajax script to update script
jQuery.ajax( {
type: "POST",
url: baseDir + "/autopost_ajax_actions.php",
data: "id=" + id + "&site_name=" + site_name + "&site_url=" + site_url + "&is_active="+ is_active + "&username=" + username + "&login_pass="+login_pass +"&action=update_site",
beforeSend: function() {
jQuery('#update_site_button').attr("disabled", true);
// shortcode edit button
jQuery('#update_site_button').html('Updating...');
// admin page edit button
jQuery('#update_site_button').val('Updating...');
},
complete: function() {
jQuery('#update_site_button').attr("disabled", false);
// shortcode edit button
jQuery('#update_site_button').html('Update');
// admin page edit button
jQuery('#update_site_button').val('Update');
},
success: function(data) {
alert("Result: " + data); // NOTHING IS HAPPENING HERE, NO ALERT DATA
if (jQuery.trim(data) === "success") {
alert("Site updated.");
// refresh page
window.setTimeout('location.reload()', 200);
} else {
alert("Some error occured, Please try again.");
}
}
});
}
Here is my custom php script for ajax actions:
// update site
if ( $_POST['action'] == 'update_site' && isset ($_POST['id']) ) {
// collect site data
$site_name = $wpdb->escape($_POST['site_name']);
$site_id = intval($wpdb->escape($_POST['id']));
$site_url = $wpdb->escape($_POST['site_url']);
$username = $wpdb->escape($_POST['username']);
$login_pass = $wpdb->escape($_POST['login_pass']);
$is_active = $wpdb->escape($_POST['is_active']);
$query = $wpdb->prepare("UPDATE " . $autopost_sites_table_name . " SET site_name = %s, site_url = %s, username = %s, login_pass = %s, is_active = %s WHERE id = %s", $site_name, $site_url, $username, $login_pass, $is_active, $site_id);
#$log->LogDebug($query);
// execute query
$result = $wpdb->query($query);
#$log->LogDebug($result);
if ( $result !== FALSE || $result !== 0) {
// return success
$response = "success";
#$log->LogDebug($response);
echo $response; // THIS RESPONSE IS NOT SHOWING ON AJAX SUCCESS
} else {
$log->LogError("Failed to update site with ID: " . $_POST['id']);
echo "Failed to update site.";
}
}
Can anyone tell me what is missing?
Change data as follows
data:{
id:id,
site_name:site_name,
site_url:site_url ,
is_active:is_active ,
username:username,
login_pass:login_pass,
action:"update_site"
}
As It is mentioned that the script is working great on local but not working on server. So it was some server issue and I was getting error for "Access-Control-Allow-Origin" in chrome network.
I just added
header('Access-Control-Allow-Origin: *');
to my ajax action script and it worked! Thanks
after
echo $response;
put
die();
See http://codex.wordpress.org/AJAX_in_Plugins
In the example it says:
function my_action_callback() {
global $wpdb; // this is how you get access to the database
$whatever = intval( $_POST['whatever'] );
$whatever += 10;
echo $whatever;
die(); // this is required to return a proper result
}
Baffled... I have a file "api.php" shown below. This is called in the jquery ajax call. When I run it from the command line I get a response that appears correct (ie not empty). When I run it in the ajax call it appears to come back empty. NOW... when I comment out the "if( $td < $lessthan )" and the two braces it all works correctly (i.e., the ajax success gets correct data.
Here is my "api.php" function:
$basedir = "calls/";
$now = time();
$lessthan = 20 * 60;
$ret = array();
$dir = opendir( $basedir );
while(($currentFile = readdir($dir)) !== false)
{
if ( preg_match( '/(.*).txt/', $currentFile, $match) )
{
$tt = #file_get_contents($basedir.$currentFile);
$td = ($now - #strtotime( $tt ));
if( $td < $lessthan )
{
$ret[] = $match[1];
}
}
}
closedir($dir);
echo json_encode(implode(',', $ret));
?>
Here is my jquery ajax call:
$.ajax({
url: 'api.php',
data: "",
dataType: "json",
type: "POST",
success: function(data, textStatus, jqXHR)
{
console.log(data + ':' + previous + ' ' + textStatus );
if( data != null && data != previous && data != "" )
{ previous = data;
$('#other').hide(); //Set output element html
$('#loaddiv').fadeOut('fast').load('reload.php?q='+data).fadeIn("fast"); //Set output element html
}
if( (data == null || data == "" ) && previous != null ) {
//$('#loaddiv').fadeOut('fast').html('No Active Calls').fadeIn("fast"); //Set output element html
$('#loaddiv').fadeOut('fast'); //Set output element html
$('#other').show();
$('#other').fadeOut('fast').load('default.php').fadeIn("fast");
previous = null;
}
},
error: function(m) { alert('error'); }
});
Any ideas on why the commenting out the "if" statement in the api.php makes the whole thing work? Or better yet, how can I leave the if statement in and for it to work.