I have a problem and I do not know how to solve it. I am working with PHP and the TDLib library to manage the Telegram API, for this, I make asynchronous calls through the JSON interface:
https://core.telegram.org/tdlib/getting-started#tdlib-interface
The Telegram API works through updates. The program receives the Telegram updates that must be answered properly in the order they are received. For this, I have a script with a 'while' cycle that works correctly for me. Here is an example of the algorithm:
void *client = td_json_client_create();
// somehow share the client with other threads, which will be able to send requests via td_json_client_send
const double WAIT_TIMEOUT = 10.0; // seconds
int is_closed = 0; // should be set to 1, when updateAuthorizationState with authorizationStateClosed is received
while (!is_closed) {
const char *result = td_json_client_receive(client, WAIT_TIMEOUT);
if (result) {
// parse the result as JSON object and process it as an incoming update or an answer to a previously sent request
}
}
td_json_client_destroy(client);
Well, the problem is that at any given time the update status of the API is "Waiting for phone number", at which time the user should be asked for the phone number. Subsequently, after several update states, Telegram sends a code to that phone number, so again my application must request the user to enter the received code when the status of the API is "Waiting for the code".
For this, I programmed two forms, one to request the phone number and another to request the code. The problem is that the forms are not shown until the script finishes, which does not help.
I tried to handle the flow of the script with break or return as the case may be, and this time I get the forms displayed at the right time, but the expected execution of the script ends, after sending the forms it becomes to execute all the code from the beginning, restarting the variables.
Anyway, I hope I have explained correctly and so that someone can give me better advice because I am really lost.
Related
I am building an iOS matching app on Objective C where a user needs to continuously keep tapping on an image, and on every tap, a request (match.php) is called on the server to check if that image is found or not. If the image is present on the server, the server will send back a positive response, and if it is absent, it will not send any response.
If a positive response is received, the app shows a "Found" alert on the screen. After every tap, a new image is presented to the user.
My problem is, if I wait after tapping on one image, it works properly as I get the desired positive response form the php file for that particular image and then the alert may or may not be shown. But if I continue tapping on consecutive images, I don't get the old responses, and the alert does not popup even if it is present on the server. I get the response only from the last image on which I wait.
Is there any solution for this? Can I queue the responses so that for every server call, I get a response? Currently it seems on every tap the connection is overwritten and old ones get lost?
I am using NSURLConnection to make the server call, and the alert is shown in connectionDidFinishLoading depending upon the response I get. In the middle of these I am also using didReceiveData to append the data in the response and also didReceiveResponse to check response.
I know I should be using NSURLSession, but will it solve this problem, or is there something else I need to do?
I am calling the server via AJAX and I get the response of the server by checking the XmlHttp object properties like:
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){ // AJAX succeeded }
}
Now, I have a timeout mechanism to wait for 10 seconds using:
setTimeout();
in Javascript for the request to be executed, in case I didn't get the status 200 for the request, then I abort the request via:
xmlHttp.abort()
and then I show a timeout message and I show a button to resend this request.
The AJAX request works perfect in 98% of time but:
The problem when my internet is shaking, I send the request successfully but when the response tries to come back, the internet doesn't work well and I lose the response, so in this case the timeout message will be triggered to user (request not completed, please try again) but actually in the server side (PHP), the request is executed successfully and this request is attached to email to be sent to user, so the user will get the email that the request is done but also a timeout message is seen for the user.
So what shall I do? When internet is off completely, timeout mechanism works fine! But when the ISP has such internet problem (shaking quickly), how can I do to prevent the PHP from executing?
Thanks for your help
You should leave as is , unless it is of critical importance to achieve this redundancy.
In case it is critical :
Instead of immediately throwing an error message, you could retry to send the request 2 or 3 times. This would give the server more chances to respond to the request.
To do that, you'd have to make sure that the same request isn't processed more then once (in your case sending the mail) - you'd have to implement a simple system in your php to cache responses and recognize requests that were already fulfilled so they wont be processed again.
Create an unique id in javascript and send it as a parameter in your ajax.
Use a session array to store the responses of your requests, keyed by this unique id.
When a request come in, check the responses array to see if it was already fulfilled, in which case you just echo back the cached response without processing.
I'm using the http service in AngularJS to make requests to my PHP API. It's a Phonegap iOS app, using AngularJS as the main framework.
In one call, I'm using the Facebook Javascript API to get the friends list of a user, encode that and send it to my API, match the emails to a list of our app users, then send the data back to the app.
I do exactly the same thing with the contacts from the phone, which I access using Phonegap.
Using console.log() I've confirmed that loading the contacts and facebook friends data from the device take less than a second.
The problem is mapping the Facebook friends list via the API takes about 20 seconds, but contacts only takes about 2 seconds.
I've manually forced the facebook list to be empty, var friends = [], and the process is nearly instant, but if I send 1 or 300 facebook contacts it gets really slow.
I've check the code on the live server by processing it with hard coded data and it takes about 0.01 seconds (so no HTTP POST, just the php logic).
I've also placed console.log() commands before the http.post() and during the success function:
console.log('http.post started');
$http.post(
$rootScope.api_url + '/friends/map/',
{values: hashes.values},
).success(function(data,status,headers,config){
console.log('http.post finished');
// process data
}).error(function(data,status,headers,config){
// log error
});
And in addition to that used PHP error_log to tell me when the start of the PHP processing occurs, and just before the result is returned:
<?php
// includes
require_once("../../../configs/config.".get_current_user().".php");
function process_request() {
error_log('started processing');
// decode POST data, work out API method etc
$return_data = $caseObject->process_data( $method, $arr_rest_data, $arr_req_data, $extra_data );
error_log('data processed');
return $return_data;
}
echo GibberishAES::enc( json_encode( process_request() ), IOS_API_PASSPHRASE );
?>
So that gives me a log before the Javascript sends the data, before and after the PHP processes it and after the Javascript receives a response.
Watching the logs get output, the 20s delay is between the following:
console.log('http.post started');
error_log('started processing');
So the delay seems to be in the upload. No data has been AES decoded by that point, and I've checked and the facebook data is an encoded string about 17k characters long, and the contacts data is 22k characters long. So it's not the size of the post, at least I don't think.
To summarise, I've got an http.post request in AngualrJS that is taking about 20s, very similar to another request that takes around 2s, the PHP code itself executes in under 1 second, and the delay seems to be between the start of the javascript http.post call and the beginning of the php processing code.
Any one know how I can work out what is causing the delay? Where should I be looking to narrow this down?
For anyone landing here with a similar issue:
The delay seems to be related with $http's request pre-processing and internal handling.
Using "plain old" XHR (eliminating $http) could speed things up considerably (at the cost of lost functionality and Angular-integration, of course).
This is a JavaScript question, but not an AJAX question. Is there a way to cancel a post once it has been submitted and is in motion?
So the user hits the post button - all is well and form is submitted PHP is ready to catch the details.
For whatever reason there is network congestion and the server does not respond.
I want to give the user a chance to post again after a time has passed.
Is there a way to cancel the actual POST once it has been sent?
Is there a way to actually detect - on the server side - that a post was received? (In this case data is to be saved in the database)
I'm imagining the whole post procedure has a beginning and an end on the server side?
Or is there a way to know for sure that the post is going nowhere? It has failed and that's the end of it?
Is there a way to cancel the actual POST once it has been sent?
No, not from the server. Only from the client. You can chose to not respond to the request, but to cancel it "in the middle" is not possible from the server without some overly complicated acrobatics which you really shouldn't be doing.
Is there a way to actually detect - on the server side - that a post
was received?
Your code will only run once a request is received; so by default - if your code is running - request is received. You can use any of the logging mechanisms provided by PHP to log this event; or just check the web server logs.
I'm imagining the whole post procedure has a beginning and an end on
the server side?
Everything starts from the client, and it ends with the client as well. The client requests a resource. If there a no clients, your code is sitting idle twiddling its thumbs. Once the server receives a request from a client, it maps the request URL to a resource and then needs to deliver a response back to the client.
All web requests happen this exact same way. They are started from the client's side; and they all end when the client receives a response and the connection is closed. Then the whole cycle starts again for a new request.
Is there a way to know for sure that the post is going no where. It
has failed and that's the end of it?
If your code was not called; then there was an error at the server end (perhaps misconfiguration). The key thing to remember is the client will always get a response; and it is up to you to figure out what happened.
The best way to do this is to have smart logging in your application - or generally monitoring the server logs (where are requests are tracked).
If a post has gone "no where", the corresponding log entry will tell you. If the log entry does not show any errors and the action that you had expected (for example, a database record was created) hasn't happened - this means the problem was with your code.
If you have a requirement to make sure that a record was created only if a request was successful then use transactions if your database supports them.
What I'm doing at the moment is creating a row in a table for each Facebook request that gets sent. Then, every time a user opens up the FB friend picker to send a request I make a call to a php file that requests information from that table and returns with a list of the FB user ids of all the people they have sent a request to in the last 24 hours. I do this for each type of request the user can send.
The issue I'm having at the moment is that if the user initiates a request, sends them off to a number of people, and then immediately opens the FB friend picker again the previous request action's records have not yet all been added to our internal table. Thus, the players, if they go fast enough, can send multiple requests to the same FB friends.
Is there a way, on the FB side, to limit this behavior Or is this entirely up to the developer to constrain? For either case, is there a recommended method by which I should achieve this behavior? Thank you.
Update
It occurred to me that our DB is keeping multiple requests from being entered on a per-user-per-24-hour period. What I do now is simply allow the second request to be made on the FB side and when the code attempts and fails to enter the second row into our DB it makes a FB Graph call that uses the app's auth_token to delete the request from Facebook itself. This means that it will show up for a moment on the receiving player's request page on Facebook but since it isn't linked with a row in the internal DB the user won't receive any reward for clicking-thru anyway.
Thanks for the suggestions, though, everybody. #Gil Birman I went ahead and accepted your answer since it's perfectly valid, even if it's not what I ultimately used to fix the problem. Thanks!
There are several ways to solve the lag problem you mentioned, one way would be to disable your send request button via javascript as soon as it is pressed. In your javascript code, instead of immediately displaying the send request dialog via FB.UI, send a json request to your server. Only when the server responds should you display the fb send request dialog. Also, the response that the server sends should include the list of friends to exclude. After the fb request is sent your javascript code should send one more json request to the server to indicate what rows in the database needs to be updated. Only when the server responds this second time should you finally re-enable your send request button.
However, there is no way to actually limit the # number of requests that your user can send. That is, no matter how well you design your javascript/php code, your user could still theoretically invoke the request dialog via the Javascript console to completely bypass your attempts to secure the app.