SSE stays on pending while AJAX is running - ajax

In my project, I have a long-running process which is called by AJAX. Duration can be 1 to 15 mins.
While AJAX is running, I want to give updates to users. It just should show simply how many rows left to add into the database.
I found out that there are a few different options to realize this. Polling, SSE or WebSockets. I never worked with WebSockets, and I couldn't find a good example.
I'm trying now with SSE which I quite understand, and it is working properly.. but when the AJAX start running the connection to the eventSource will be pending. So while AJAX is running, there are no updates received.
Code:
<script type="text/javascript">
var es;
function checkProgress(id){
es = new EventSource('checkProgress.php');
es.addEventListener('message', function(e) {
console.log(e.data);
}, false);
}
checkProgress(1);
$(function() {
$('.submit').on('click', function() {
var form = $('form')[0];
var form_data = new FormData(form);
$.ajax({
type: 'POST',
url: 'submit.php',
contentType: false,
processData: false,
data: form_data,
success:function(response) {
console.log(response);
}
});
return false;
});
});
</script>
Screenshots:
Network log
Now actually I still didn't find any reference or example of how to implement SSE while there is an AJAX process running. All reference or examples give examples to let the getProgress file to do something.

I see you're using PHP. My best guess would be that you're also using the built-in PHP session management. The problem with this is that accessing the session is an exclusive operation. I would guess that your AJAX operation has opened and locked the session, preventing your SSE script from also opening the session. You might consider not opening the session or opening it read-only(Dead Link) (Archived).

Related

How safe it is to use Ajax request for every second

I have created a chat room which uses ajax request to check for new message every second by using setTimeOut function, I achieved this but my only question is that, is it okey to request data from server after every second? or it may cause some problems? below is my code:
function refresh(){
setTimeout(function(){
$.ajax({
type: 'POST',
url: 'checkNewMessage.php',
data: { sender:$sender, recipient:$recipient},
success: function(response) {
$('#newComm').val(response);
if($('#newComm').val()>$('#oldComm').val()){
$.ajax({
type: 'POST',
url: 'appendNewMessage.php',
data: { sender:$sender, recipient:$recipient},
success: function(response) {
$("#chatRoom").prepend(response).fadeIn(4000);
$('#oldComm').val($('#newComm').val());
}
});
}else{}
}
});
refresh();
},1000);
}
Well, this is a question with a depends on answer.
Polling the server with timed requests is not the best way of achieving what you would like to achieve. At this place I recommend using WebSockets: https://developer.mozilla.org/en-US/docs/Glossary/WebSockets
But back to your question. It depends on your server and the load it is going to take. Lets say you have ten active users. So your server would take about 10 requests per second - not too much.
You could run a benchmark and see how many requests per second your server can handle. But handling requests is not the same like answering each request.
If you don't have so many users on your chat, you might be ok with this approach. For bigger loads I highly recommend to switch to WebSockets.

How to return a Thenable CompletionList

I'm trying to improve performance of a monico editor completion item provider (it is currently making ajax calls to get the appropriate items ... the custom language is very large and complex).
I'm wonderingf if/how returning a Thenable CompletionList might help with this.
https://microsoft.github.io/monaco-editor/api/interfaces/monaco.languages.completionitemprovider.html
We initially started with a synchronous ajax call so that we are sure to have results to present, but that was causing too much blocking/interruption in typing flow. Now the ajax call is asynch but is not returning fast enough and we get a 'No suggestions' message.
I figured it out. In case anyone else is wondering how to do the same. From the provideCompletionItems function ...
return new Promise(function(resolve, reject) {
$.ajax({
url: 'someaddress.com',
dataType: 'json',
success: function(res) {
// create your keywords json here
resolve({items: keywords, isIncomplete: true});
},
error: function(xhr, error){
reject({items: [], isIncomplete: true})
},
});
});
The monaco editor will then display a nice little set of animated dots as a loading indicator while the ajax call happens.

Delay GET until all POST methods have completed, not just begun

I am experiencing two issues with my jQuery record-inserting process, and I am hoping that this wonderful SO community can help me to solve at least one of those issues. These are the issues:
Issue 1 - Intermittent server delay
The first issue relates to the fact that my Ubuntu 10.04 server seems to exhibit intermittent, 4.5 second delays when doing a POST of data to the mySQL database. Most POST commands are executed within a normal amount of milliseconds, but when a delay occurs, it always seems to be for approximately 4.5 seconds. This is not a busy, public server so it shouldn't be a matter of server load being the problem. These short videos demonstrate what I am trying to explain:
Video 1
Video 2
I have posted a question on serverfault and am awaiting some input from that forum which is probably more appropriate for this Issue 1.
Issue 2 - Timing of jQuery POST and GET Methods
The real issue that I am trying to resolve is to prevent the call to GET before all of the calls to POST have completed. Currently, I have implemented $.when.apply to delay the sending of GET. Here is the code for that:
function(){
$.when.apply(undefined, InsertTheAPPs()).done(function (){
$.ajax({
url: sURL + "fileappeal/send_apps_email",
success: function() {
var m = $.msg("my message",
{header:'my header', live:10000});
setTimeout(function(){
if(m)m.setBody('...my other message.');
},3000);
setTimeout(function(){
if(m)m.close(function(){
window.location.replace(sURL+'client/view');
});
},6000);
$('#ajaxShield').fadeOut(1000);
},
error: function(){
$.msg("error message",
{header:'error header', live:10000});
}
});
});
}
My problem arises due to the delay described above in Issue 1. The GET method is being called after all of the POST methods have begun, but I need the GET method to wait until all of the POST methods have ended. This is the issue that I need assistance with. Basically, what is happening is happening wrong here is that my confirmation email is being sent before all of the records have been completely inserted into the mySQL database.
Here is the code for the jQuery $.each loop. This is the code that needs to not only begin, but must end before the ajax call to fileappeal/send_apps_email above:
function InsertTheAPPs(){
$('input[name=c_maybe].c_box').each(function(){
var jqxhrs = [];
if($(this).prop('checked')){
var rn = $(this).prop('value');
jqxhrs.push(
$.ajax({
url: sURL + 'fileappeal/insert_app',
type:"POST",
dataType: 'text',
data: {'rn': rn},
error: function(data) {console.log('Error:'+rn+'_'+data);}
})
)
return jqxhrs;
}
});
}
Anyone have any suggestions for how I can workaround the server delay issue and prevent the call to the GET before all of the POST methods have completed? Thanks.
There's a small problem with your post. After you resolve it, this post should help you finish out your code: jQuery Deferred - waiting for multiple AJAX requests to finish
You're returning inside the .each but the function itself doesn't return anything. So your delay is not being given the array of ajax calls to wait for. And also, since your jqhrs is defined inside the each, the scope is per iteration over each c_box. Your method should look like this:
function InsertTheAPPs(){
var jqxhrs = [];
$('input[name=c_maybe].c_box').each(function(){
if($(this).prop('checked')){
var rn = $(this).prop('value');
jqxhrs.push(
$.ajax({
url: sURL + 'fileappeal/insert_app',
type:"POST",
dataType: 'text',
data: {'rn': rn},
error: function(data) {console.log('Error:'+rn+'_'+data);}
})
)
}
});
return jqxhrs;
}
You can also make your code easier. Since you just want to know if something is checked you can use the jquery pseudo class filter :checked such as:
function InsertTheAPPs(){
var jqxhrs = [];
$('input[name=c_maybe].c_box').filter(':checked').each(function(){
var rn = $(this).prop('value');
jqxhrs.push(
$.ajax({
url: sURL + 'fileappeal/insert_app',
type:"POST",
dataType: 'text',
data: {'rn': rn},
error: function(data) {console.log('Error:'+rn+'_'+data);}
})
)
});
return jqxhrs;
}
You could combine the filter on :checked into the main filter such as $('input[name=c_maybe].c_box:checked') but I left it in long form to really demonstrate what was going on.

Converting AJAX call to avoid cross-domain problems

I m trying to convert the following code to another AJAX call, in order to not have cross-domain problems!
This is my original code:
<script>
$(document).ready(function() {
$("#os").load('http://www.a.gr/os #livesos');
var refreshId = setInterval(function() {
$("#os").load('http://www.a.gr/os #livesos');
}, 60000);
$.ajaxSetup({ cache: false });
});
</script>
And here is a sample code for what i want to do, but i dont know how...
$.ajax({
type: "GET",
cache: false,
url: 'http://www.a.gr/os',
dataType: "???",
.
.
.
.
});
Can someone help me please?
Your best bet to avoid cross-domain issues is to have the phone call your server, and the server can call the other servers to get the data needed.
There are a couple of benefits to this, one being that you can cache recent calls, if it doesn't change often, and more quickly send it back to the client.
Also, if you want to later change the url or make additional calls to return richer data, you can do that without affecting the client.

Browers entering "busy" state on Ajax request

I am currently implementing a sort of HTTP Push using Long Polling for browsers that don't support multipart ajax responses.
I have to admit that while the server side is working fine, i am relativly new to front end javascript development, and thus may have made some obvious mistakes
The problem is as follows LongPolling works perfectly on IE 6,7,8 and Firefox ( even though Firefox uses multipart i tested it with long polling too ) but Safari and Chrome enter
the browsers "busy" state during the ajax requests. ( they show the windows wait cursor, and Safari also shows its "Loading" indicator in the title bar )
This is of course not desireable..
Here is my code to do the long poll based on Jquery 1.4.1:
function MepSubscribeToQueueLongPoll(name, callback) {
var queueUrl = MepGetQueueUrl(name, "LongPoll");
MepLongPollStep(queueUrl, callback);
};
function MepLongPollStep(url, callback) {
$.ajax({
url: url,
async: true,
cache: false,
success: function (data,status,request) {
callback(request.responseText);
MepLongPollStep(url, callback);
}
});
};
Note that i am bypassing the data parsing functionality of Jquery by passing the request.responseText directly to the callback because Jquery does not seem to support multipart ajax respones and i wanted to be consistent across communication paths.
Since no better answer has stepped forward, I wonder if a simple timeout would solve the problem. Sorry to give a "guess" instead of a "I know this to be true answer", but this might actually fix it.:
function MepLongPollStep(url, callback) {
$.ajax({
url: url,
async: true,
cache: false,
success: function (data,status,request) {
callback(request.responseText);
window.setTimeout( function(){
MepLongPollStep(url, callback);
},10);
}
});
};

Resources