Is this a true long polling? - php

After a lot of trials, I am successfully able to maintain continuous server connection with a database.
Now code keep checking and show the messages, if there are new in database.
Please review and tell:
if there is true long polling technique used in this code? If it is not, then please suggest, where I am wrong(deviating from long polling) and how this can be made a true long polling.
Currently, I am getting these errors. However still it maintains the continous connection with database.
**each time only one message is pulled instead of all **(I used each loop but it stops the long polling)
After every 10/15 seconds, token error appeares (Parse error (syntax error=unexpected token)).
var last_msg_id = 2;
function load_msgs() {
$.ajax({
type:"Post",
url:"getdata.php",
data:{
last_msg_id:last_msg_id
},
dataType:"json",
async:true,
cache:false,
success:function(data) {
var json = data;
$("#commidwin").append(json['msg']);
last_msg_id = json["last_msg_id_db"];
setTimeout("load_msgs()", 1000);
},
error:function(XMLhttprequest, textstatus, errorthrown) {
alert("error:" + textstatus + "(" + errorthrown + ")");
setTimeout("load_msgs()", 15000);
}
});
}
Php file is here
$last_msg_id=$_POST['last_msg_id'];
$last_msg_id_db=1;
while($last_msg_id>$last_msg_id_db){
usleep(10000);
clearstatcache();
$sql=mysqli_query($db3->connection,"SELECT * FROM chat_com where id>'$last_msg_id' ORDER by id ASC");
$sql_m=mysqli_query($db3->connection,"SELECT max(id) as maxid FROM chat_com");
$row_m=mysqli_fetch_array($sql_m);
$last_msg_id_db=$row_m['maxid'];
while($row=mysqli_fetch_array($sql)){
$textt=$row['mesg'];
$last_msg_id_db=$last_msg_id_db;
$response=array();
$response['msg']=$textt;
$response['last_msg_id_db']=$last_msg_id_db;
}
}
echo json_encode($response);

Polling is a bit harder than a simple while : just because generally all things you output to the browser will be interpreted when complete. Your example is quite clear :
success:function(data) {
var json = data;
$("#commidwin").append(json['msg']);
last_msg_id = json["last_msg_id_db"];
setTimeout("load_msgs()", 1000);
},
jQuery will wait until the response is complete to build your data variable and then will call your success callback.
One way to create long-polling is to have a task and a follower :
the task is the "infinite" loop, it displays nothing but just catch and trigger events, put in a "box".
the follower is an ajax call made every X seconds, it looks inside the "box" filled by the task, and immediately act inside the page.
Here is an example of long-polling, there is no follower, just an event (release) that stops the poll, but you'll get the idea :
<?php
// For this demo
if (file_exists('poll.txt') == false)
{
file_put_contents('poll.txt', '');
}
// If this variable is set, a long-polling is starting...
if (isset($_GET['poll']))
{
// Don't forget to change the default time limit
set_time_limit(120);
date_default_timezone_set('Europe/Paris');
$time = time();
// We loop until you click on the "release" button...
$poll = true;
$number_of_tries = 1;
while ($poll)
{
// Here we simulate a request (last mtime of file could be a creation/update_date field on a base)
clearstatcache();
$mtime = filemtime('poll.txt');
if ($mtime > $time)
{
$result = htmlentities(file_get_contents('poll.txt'));
$poll = false;
}
// Of course, else your polling will kill your resources!
$number_of_tries++;
sleep(1);
}
// Outputs result
echo "Number of tries : {$number_of_tries}<br/>{$result}";
die();
}
// Here we catch the release form
if (isset($_GET['release']))
{
$data = '';
if (isset($_GET['data']))
{
$data = $_GET['data'];
}
file_put_contents('poll.txt', $data);
die();
}
?>
<!-- click this button to begin long-polling -->
<input id="poll" type="button" value="Click me to start polling" />
<br/><br/>
Give me some text here :
<br/>
<input id="data" type="text" />
<br/>
<!-- click this button to release long-polling -->
<input id="release" type="button" value="Click me to release polling" disabled="disabled" />
<br/><br/>
Result after releasing polling :
<div id="result"></div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
// Script to launch polling
$('#poll').click(function() {
$('#poll').attr('disabled', 'disabled');
$('#release').removeAttr('disabled');
$.ajax({
url: 'poll.php',
data: {
poll: 'yes' // sets our $_GET['poll']
},
success: function(data) {
$('#result').html(data);
$('#poll').removeAttr('disabled');
$('#release').attr('disabled', 'disabled');
}
});
});
// Script to release polling
$('#release').click(function() {
$.ajax({
url: 'poll.php',
data: {
release: 'yes', // sets our $_GET['release']
data: $('#data').val() // sets our $_GET['data']
}
});
});
</script>
Demonstration : here.

Related

auto refresh the div with dynamic data

I have a div section. I want to reload this section every 5 seconds. How do I do this. Here is my code:
<script>
$("#send_parent_general_chat").submit(function()
{
var rec = $("#data").val();
var msg = $("#msg").val();
var dataString = 'rec='+ rec + '&msg='+ msg;
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>" + "Client/send_general_parent_chat_msg/<?php echo $per_job->id;?>",
data: dataString,
cache: false,
success: function(result){
$('#display_general_msg').html(result);
$('#send_parent_general_chat')[0].reset(); //form reset
}
});
return false;
});
</script>
<script>
$(document).ready(function(){
setInterval(function(){
// alert("===111==");
$("#display_general_msg").load('<?php echo base_url(); ?>" + "Client/refresh_general_parent_chat_msg/<?php echo $per_job->id;?>')
}, 5000);
});
</script>
I have created one more controller for refreshing the div I have used the time interval function but it is not loading, it shows this error:
Access forbidden!
You don't have permission to access the requested object. It is either read-protected or not readable by the server.
If you think this is a server error, please contact the webmaster.
Error 403
I need to refresh only the div content not the whole page.
How do I achieve this?
You can Use :
setTimeout(function()
{
Your_Function(); //this will send request again and again;
}, 5000);
Replace Your_Function with your Function Name.
Hope this will help !!
Below is an example which will update the contents in every 5 seconds using php websockets. This is a simple example, but you can use it to modify to fit for your application needs. You don't need the timeout functions on the client side here we use server sleep
Install the Workerman socket library
composer require workerman/workerman
The client side code
<!DOCTYPE HTML>
<html>
<head>
<script type = "text/javascript">
function WebSocketTest() {
if ("WebSocket" in window) {
//alert("WebSocket is supported by your Browser!");
// Let us open a web socket
var ws = new WebSocket("ws://localhost:2346");
ws.onopen = function() {
// Web Socket is connected, send data using send()
ws.send("Message to send");
//alert("Message is sent...");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
//alert("Message is received..." + received_msg);
document.getElementById("demo").innerHTML = "Timestamp is updated every 5 sec " +received_msg;
};
ws.onclose = function() {
// websocket is closed.
alert("Connection is closed...");
};
} else {
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
</head>
<body>
<div id = "sse">
Run WebSocket
</div>
<div id="demo" style="font-size: 64px; color: red;"></div>
</body>
</html>
The Server side code
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// Create a Websocket server
$ws_worker = new Worker("websocket://0.0.0.0:2346");
// 4 processes
$ws_worker->count = 4;
// Emitted when new connection come
$ws_worker->onConnect = function($connection)
{
echo "New connection\n";
};
// Emitted when data received
$ws_worker->onMessage = function($connection, $data)
{
// Send hello $data
while(true) {
$connection->send(time());
sleep(5); //Sleep for 5 seconds to send another message.
}
};
// Emitted when connection closed
$ws_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// Run worker
Worker::runAll();
The backend service can be started with the following command from the terminal or you can autostart on boot if you want.
$php index.php start
Here index.php is our backendnd file name.
Just start the service and load the page then you can see the timestamp is updated every 5 seconds which comes from the server side. This is a working example tested on my local machine. Try and let me know if you need any other help.
The output
you can also try below one:
setInterval(function(){
loadlink() // this will run after every 5 seconds
}, 5000);
setInterval approach will be more accurate than the setTimeout approach
// or
$(function(){ // document.ready function...
setTimeout(function(){
$('form').submit();
},5000);
});

using ajax to fetch a result from php and reload page

So I have been working on this for hours now, I have read a bunch of StackOverflow posts and I am still having no luck.
I have a page that has 2 sections to it, depending on the int in the database will depend on which section is being displayed at which time.
My goal is to have the page look to see if the database status has changed from the current one and if it has then refresh the page, if not then do nothing but re-run every 10 seconds.
I run PHP at the top of my page that gets the int from the database
$online_status = Online_status::find_by_id(1);
I then use HTML to load the status into something that jquery can access
<input type="hidden" id="statusID" value="<?php echo $online_status->status; ?>">
<span id="result"></span>
So at the bottom of my page, I added some jquery and ajax
$(document).ready(function(){
$(function liveCheck(){
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST',
success:function(data){
if(!data.error){
$newResult = $('#result').html(data);
window.setInterval(function(){
liveCheck();
}, 10000);
}
}
});
});
liveCheck();
});
this then goes to another PHP page that runs the following code
if(isset($_POST['search'])){
$current_status = $_POST['search'];
$online_status = Online_status::find_by_id(1);
if($current_status != $online_status->status){
echo "<script>location.reload()&semi;</script>";
}else{
}
}
the jquery then loads into the HTML section with the id of "result" as shown earlier. I know this is a very bad way to do this, and as a result, it will work at the beginning but the longer you leave it on the page the slower the page gets, till it just freezes.
If anyone is able to point me towards a proper method I would be very grateful.
Thank you!!
js:
(function(){
function liveCheck(){
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST',
success:function(data){
if(data.trim() == ''){
location.reload();
}else{
$('#result').html(data);
window.setTimeout(function(){
liveCheck();
}, 10000);
}
}
});
}
$(function(){
liveCheck();
});
})(jQuery)
php:
<?php
if(isset($_POST['search'])){
$current_status = $_POST['search'];
$online_status = Online_status::find_by_id(1);
if($current_status != $online_status->status){
$data = '';
}else{
$data = 'some html';
}
echo $data;
}
Your page is slowing down because you are creating a new interval every time you call the liveCheck function. Over time, you have many intervals running and sending requests to your PHP file concurrently. You can verify this behavior by opening the developer console in your browser and monitoring the Network tab.
What you should do instead is set the interval once, and perform the $.ajax call inside that interval. Additionally, it's good practice to not send a new request if a current request is pending, by implementing a boolean state variable that is true while an request is pending and false when that request completes.
It looks like the intended behavior of your function is to just reload the page when the $online_status->status changes, is that correct? If so, change your PHP to just echo true or 1 (anything really) and rewrite your JS as:
function liveCheck() {
if (liveCheckPending == true)
return;
liveCheckPending = true;
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST'
}).done(function(data){
if (!data.error)
location.reload();
}).always(function(data){
liveCheckPending = false;
});
}
var liveCheckPending = false;
setInterval(liveCheck, 10000);

php ajax - auto refresh a div only if returned data is not empty

I am using bootstrap , php and mysql for an application . With this , whenever the users are logged in , the admin will post messages across to all users that will be displayed as an alert on the page . Below is my ajax code :
$.ajaxSetup(
{
cache: false,
beforeSend: function() {
$('#admin_message').hide();
},
complete: function() {
$('#admin_message').show();
},
success: function() {
$('#admin_message').show();
}
});
var $admin_msg = $("#admin_message");
$admin_msg.load("get_message_board.php");
var refreshId = setInterval(function()
{
$admin_msg.load('get_message_board.php');
}, 10000);
Below is my alert holder holder
<div class="alert alert-success" id="alert_holder">
<p id="admin_message" style="text-align: center;font-size: 20px"></p>
</div>
PHP SCRIPT :
include './functions.php';
$sql = "select message from msg_db3 where user_group ='".$_SESSION['active_user_group']."' order by id DESC LIMIT 1";
$temp = return_results($sql);
echo $temp['0']['message'];
Now i want to make sure that the div (with id='alert_holder') is hidden by default and shows up only if echo $temp['0']['message'] is not empty .If it is empty , it should be hidden . Also the transition is a bit odd since it shakes the entire page while bringing the alert up on the screen .
Please advice on the above .
THanks in advance .
EDIT:
can you try with normal Ajax?
$.ajax({
url: "get_message_board.php"
})
.done(function( data) {
console.log(data);
if(data.length>0){
$('#admin_message').show();
} else {
alert('not found');
}
}
});
Check your response length and show if it's not null
success: function(data) {
if(data.length>0){
$('#admin_message').show();
}
}
In php script you can change to
if(isset($temp['0'])){
echo $temp['0']['message'];
}
The main problem with your code is with
complete: function() {
$('#admin_message').show();
},
This code will show #admin_message every time when ajax is completed.
if you remove this unnecessary part you can make only my first change with if detection.

Understanding AJAX php script for clue game practice

I'm trying to understand the relationship between a PHP script I'd like to run to keep track of progress and the front end work that has taken place. Its 2 clues in a game practice. Once the clue is inputted correctly everything occurs as below and I want to add a script that sends to MYSQL.
I'm working on the script now, but I'm trying to figure out at what point I'd introduce this. Is there anything I'd need within my PHP to distinguish it as AJAX. As in to run it in the background? Do I just "include" it as I would part of another larger PHP script?
The script in my mind will send a 1 if correct or 0 if still wrong. This way I can easily determine without having to deal with clues. The clues are irrelevant in my thinking, but what is your opinion on this?
// =====clue 1====================////////////////// clue 1 **************
//**********************************========================
$(document).on('click', '.btn-clue', function(){
if($i!=1){
$.ajax({
type: "POST",
url: "includes/post_clue_progress",
data: { clueTwo: "1", usernameClue: "<?php echo $manager; ?>" }
})
.done(function( msg ) {
// msg is any data that is echoed in the php script or output to screen is some way
$("#clueWrongTwo").hide();
$("#mySecondDivClueTwo").remove();
$("#clueTwo").remove();
$("#clue2Input").remove();
$two.show();
$("#clueTwoInputCorrect").slideDown('slow').show();
$i++;
});
} else {
$("#mySecondDiv").remove();
var mySecondDiv = $('<div id="mySecondDiv"><img src="images/check-x-mark.png" /></div>').show('slow');
$('#clueWrongOne').append(mySecondDiv);
}
}
});
// =====clue 2====================////////////////// clue 2*********=========
$(document).on('click', '.btn-clueTwo', function(){
if($i!=1){
//checking if textbox has desired value (1 in this case),
//in your application you would be passing the textbox value to
//ajax here and making the check at server side
var $two = $('#twoClueShow');
var x = $("#clueTwoInput").find('input[type=text]').val();
if(x == 'C' || x == 'CS') {
// if answer correct you should load data from ajax
// and append it to a container
$("#clueWrongTwo").hide();
$("#mySecondDivClueTwo").remove();
$("#clueTwo").remove();
$("#clue2Input").remove();
$two.show();
$("#clueTwoInputCorrect").slideDown('slow').show();
$i++;
} else {
$("#mySecondDivClueTwo").remove();
var mySecondDivClueTwo = $('<div id="mySecondDivClueTwo"><img src="images/check-x-mark.png" /></div>') .show('slow');
$('#clueWrongTwo').append(mySecondDivClueTwo);
}
}
});
Above is where I've been able to get. Now here is where I'm getting confused. I now want to send to the database that the answer has been answered correctly through AJAX, correct? Would I just include_once my php script in the commented area.
I was thinking of creating a script that filled a 1 if correct and 0 if not correct to make life easier. Let this do the work as I don't need to reintroduce the inputs or re use. This way once the page has reloaded I could simply not output the inputs again and use this info to determine what is displayed and where they are at in the clue game. Basically saving progress.
Is there something specific to use when building my normal PHP. I guess that and where to "include" it is where I'm confused.
MY button for reference
<div id="clueOneInput">
<input type="text" id="clue1" class="clue-text form-control" placeholder="Enter Clue 1 here and check"/>
</div>
<input type="button" id="clue1Input"class="btn btn-primary btn-clue" value="Check">
Update :
// =====clue 1====================////////////////// clue 1**********************************************************************========================
$(document).on('click', '.btn-clue', function(){
if($i!=1){
//checking if textbox has desired value (1 in this case),
//in your application you would be passing the textbox value to ajax here and making the check at server side
var $one = $('#oneClueShow');
var x = $("#clueOneInput").find('input[type=text]').val();
if(x == 'd' || x == 'dr')
{
//if answer correct you should load data from ajax and append it to a container
$.ajax({
type: "POST",
url: "includes/post_clue_progress",
data: { clueOne: "1", usernameClue: "<?php echo $manager; ?>" }
})
.done(function( msg ) {
// msg is any data that is echoed in the php script or output to screen is some way
$("#clueWrongOne").hide();
$("#mySecondDiv").remove();
$("#clueOne").remove();
$("#clue1Input").remove();
$one.show();
$("#clueOneInputCorrect").slideDown('slow').show();
$i++;
});
}
else
{
$("#mySecondDiv").remove();
var mySecondDiv = $('<div id="mySecondDiv"><img src="images/check-x-mark.png" /></div>').show('slow');
$('#clueWrongOne').append(mySecondDiv);
}
}
});
// =====clue 2====================////////////////// clue 2**********************************************************************========================
$(document).on('click', '.btn-clueTwo', function(){
if($i!=1){
var $two = $('#twoClueShow');
var x = $("#clueTwoInput").find('input[type=text]').val();
if(x == 'CS' || x == 'CSU')
{
$.ajax({
type: "POST",
url: "includes/post_clue_progress",
data: { clueTwo: "1", usernameClue: "<?php echo $manager; ?>" }
})
.done(function( msg ) {
// msg is any data that is echoed in the php script or output to screen is some way
$("#clueWrongTwo").hide();
$("#mySecondDivClueTwo").remove();
$("#clueTwo").remove();
$("#clue2Input").remove();
$two.show();
$("#clueTwoInputCorrect").slideDown('slow').show();
$i++;
});
}
else
{
$("#mySecondDivClueTwo").remove();
var mySecondDivClueTwo=$('<div id="mySecondDivClueTwo"><img src="images/check-x-mark.png" /></div>').show('slow');
$('#clueWrongTwo').append(mySecondDivClueTwo);
}
}
});
In your Jquery
$.ajax({
type: "POST",
url: "yourScriptToUpdateDB.php",
data: { clue: "Wrong", user: "JoeBob" }
})
.done(function( msg ) {
// msg is any data that is echoed in the php script or output to screen is some way
$("#clueWrongOne").hide();
});

Installation progress bar php

I have a simple installer that's divided in segments, not by syntax, but just by logic. Here's how it works:
if ($_POST['install'] == "Install")
{
// fetches user values
// creates tables
// creates some files
// creates some emails
// inserts relevant stuff into the database
// finishes
}
The code is too long and unnecessary for this question. Each of those steps counts as 20% complete for the installation, how would I make a progress bar displaying the info to the user? I'd like this for two reasons, one is for them to keep track, other is for them to know they shouldn't close the browser tab before it's done.
Now my idea is to assign a variable to each part of the code, for instance $done = 20% in the first, $done = 40% in the second etc, and simply show progress bar based on that variable. The the only thing I don't know is how to show the progress bar?
Thanks
My recommended solution:
Create separate ajax requests for each step in your process like so...
// do first step
$.ajax({
url: myUrl + '?step=1',
success: function() {
// update progress bar 20%
}
});
// do second step
$.ajax({
url: myUrl + '?step=2',
success: function() {
// update progress bar 40%
}
});
// etc.
If you want to be DRY, try this:
var steps = 5;
for (var i = 1; i <= steps; i++) {
$.ajax({
url: myUrl + '?step=' + i;
success: function() {
// update success incrementally
}
});
}
With jQuery UI progressbar:
$(function() {
$("#progressbar").progressbar({
value: 0
});
var steps = 5;
for (var i = 1; i <= steps; i++) {
$.ajax({
url: myUrl + '?step=' + i;
success: function() {
// update success incrementally
$("#progressbar").progressbar('value', i * 20);
}
});
}
});
Ref. http://jqueryui.com/progressbar/#default
The best practice is to store the progress value in a db or a key-value storage system such as APC, Memcache or Redis. And then retrieve the progress with an ajax query.
A good jquery plugin is progressbar bar from jQuery-ui, and you can use json to encode the progress value:
// GET /ajax/get-status.json
{
"progress":10,
"error":"",
"warning":""
}
The page:
<div id="error" style="color: red"></div>
<div id="warning" style="color: yellow"></div>
<div id="message"></div>
<div id="progressbar"></div>
<script type="text/javascript">
jQuery(document).ready(function() {
$("#progressbar").progressbar({ value: 0 });
$.ajaxSetup({ cache: false });
function updateProgress() {
jQuery.getJSON("/ajax/get-status.json", function(response) {
if (response.error) {
$("#error").html( response.error );
return;
} else {
$("#progressbar").progressbar( 'value', parseInt( response.progress ) ); // Add the new value to the progress bar
$("#message").html( response.message );
$("#warning").html( response.warning );
if(parseInt( response.progress ) < 100){
setTimeout(updateProgress, 1);
}
}
});
}
updateProgress();
});
</script>
You can use an HTML5 progress bar.
Send ajax request and return the percent complete.
Change the progress tag's value.
<progress id='p' max="100" value="50"></progress>

Categories