So it's not a complicated matter at all, but was wondering how the Stackoverflow community would tackle this.
I wrote a facebook-style wall type thing where users enter their "status", it gets processed via jQuery Post and upon success returns a success message.
Prepending the new message to the Wall Stream would make sense, however, if another user had entered a message before the submission it would fail to show the correct time sequence...
I guess my question is this.
Should I query the latest Wall Messages inside the PHP file and echo back the entire result? That way when jQuery receives the callback it can delete whatever is in the Wall Stream and update with the new content?
I am assuming a bit on the details and purpose of your app but I probably would not bother doing anything fancy. Typing a status is pretty quick and the probability someone else beat you to the race is somewhat of an edge case yet adds complexity and a database performance hit. Also the error of showing the wrong time sequence in my opinion is forgivable in the rare case that it does occur and the user notices. There's probably bigger fish to fry somewhere else in your app.
If the nature of the app or site makes correctness important, then a possible solution is to post the id of the most recent message that has already been loaded on the client side so that the server can respond with the contents/details of messages posted after that id so the new messages can be rendered for the client. I would post an id instead of a timestamp so that there's no need for synchronization between client and server time.
Perhaps, you could pass a timestamp of last status update back to server and return all changes since that, so you could prepend all that is new.
Related
Straight to my issue, I have a database which has casino tables; each table has some places, where I can add people and remove them.
All this works fine, but when I open my project on two different browsers, I cant see the updates which I've done from the other one.
So I was thinking for AJAX request on every 5sec or something like this, but I don't like this approach.
Then I started to look for another solution and found this MQTT server, but couldn't find a good example how it works with MySQL. I saw that Mosquito-PHP library, and maybe I can get it works on my server, but I'm confused How to get the status. If someone add a person to a table. How Do I check, there is a change?
I've red that the MQTT use something as infinity loop is it good idea to check in MySQL for changes in this loop?
Thank you in advance for any suggestions; and, sorry for my English, still learning.
I believe you need to divide your complicated task into simpler parts, possibly these could be a guideline:
for each browser session you should have a last update date
whenever the browser extracts relevant data, your session's update date should be updated
you should have a last event date on the server
you should send ajax request every five seconds to the server, called heartbeat event
upon each heartbeat, the server should check whether your last update is earlier than the last event and send a response in this vein
if your ajax request yields the result that your status is not at least as new as the last update, the client-side should send another request for new info
I am trying to show the list of online users in my application. Let me explain my requirement.
I have a Mysql DB table where list of username and their status mode(either 1 or 0) are storing. I have two php pages. One is for listing down all user's name and the status mode. Second page is for editing the mode of users from 1 to 0 and vice versa.
Now I open these two pages from different system. If I change the status of one user(edit page) from one system then automatically it will reflect to the another system, where the listing page is opened, with the updated record and obviously this should happen before refresh the listing page. The same like gtalk chat users.
I am not asking the code, but please help me how to proceed to resolve the issue. Obviously, cronjob is one of the solutions, please provide another solution.
Thanks in advance.
Well cronjobs are in fact not the thing you need.
With cronjobs you can schedule a task. What you want is client side refresh when new info is found. While cronjobs are server side and always on an interval.
What you need is polling or commet
The first, polling, you use your client side to execute a script every x seconds and look if there is new info (waste of resources in my opinion).
Commet, is now a days a better solution. But often hard to implement. I used pusher for this type of stuff. You can push messages to (all) clients connected and say there is new info. And then they will update or with the message comes also the new info
To achieve something like this, you should use JavaScript and Ajax in the clientside.
Give the XMLHttpRequest a try. To make it easier you could use something like jQuery.
On the serverside you could use json to transmit the data.
Read the data from the table and put it into an array, let's call it users, the keys are the names and the values are their mode(1 or 0).
Then use json_encode(ARRAY):
//Echo the results in json format
echo(json_encode($users));
Let's say, the users 'Frank', 'Susan' and 'George' are online and 'Isabell' and 'John' are offline. Then the script would result in an output similar to this:
{"Frank":1,"Susan":1,"George":1,"Isabell":0,"John":0}
Of course you need to put this and the loading into another php-script, maybe refresh.php.
And, to read the data from the script, add some JavaScript to your view page.
Use the XMLHttpRequest to request data from the script you just added.
Or, if you use jQuery, you can simply use $.getJSON("NameOfTheScriptYouJustWrote") which returns an already parsed object.
Then use the returned data to update the list of users. And refresh it every 5-20 seconds.
And keep in mind that this is not an efficient way at all and that this will not work well if there are many clients using your service.
I want to make a page that will show all the users who are looking at that page right now. Ideally, a database would store which users are on the page and websockets would be used to update when users enter and leave.
The problem is that I don't know how to tell when users are viewing the page. I was thinking that I would be able to tell when they arrived and when they exited and add/remove accordingly. It's easy to tell when they arrive; however, it's difficult to tell when they leave - especially because users might do something like open multiple tabs, close one but keep the other open.
What is the best way to do this? I am using PHP as my server-side language.
You can use the blur and focus events on the window to toggle a variable. However, IE does some quirks which you will need to work around.
As a fallback to not working focus events, you might add a mousemove handler to the document. This might also throttle an automatic timeout which detects the loss of focus just by the fact that there was no user interaction for a specific period of time. However, you will never be able to detect a distracted user that has the site open but looks at something else...
To detect the window closing, you can hook on the unload event. This might be unreliable, but as you are using Websockets your server can easily detect a closed connection.
Well, one thing you could do, especially if you are using websockets is do a heartbeat/ping to the server every few seconds if you really wanted. If you don't get that heartbeat, you know they are not on the page anymore.... however, getting a response doesn't mean they are looking at the page, it would just mean that it is open, possibly in another tab. There is no way that I know of that will send a response to the server if the person loses focus on the page and opens another tab/window.
As Tim mentioned, Firefox and IE will run javascript in the background tabs, so there's no surefire way by simple polling to tell if the user is actually "looking" at the page or just has it open somewhere. Although I know of no way to tell if the user is actually looking at your page, a potential solution might be to bind polling to actions. So you might have some variable
var timesincelastaction=0;
var threshhold = 20;
Then
setInterval("timesincelastaction++",100);
Then
function keepAlive() {
if(timesincelastaction > threshhold) {
$.ajax(...tell the server you are alive...);
timesincelastaction = 0;
}
}
Then start thinking of actions like
$('a').mouseover(keepAlive);
$('div').mouseover(keepAlive);
$(window).scroll(keepAlive);
$(video).play(keepAlive); // okay this isn't a real one but you get the picture
So then you just brainstorm on everything the user can possibly be doing on the page that requires their attention and use those as your benchmark.
This seems a little intense I know, there's probably some nice ways to optimize it. Just thinking out loud. Curious to see what others come up with.
Every time one of your PHP scripts run, some user or entity has requested to view a page on your site (this usually occurs every time your script runs).
It is more challenging to detect when a user has left your page, which is why most online indicators are simply a timeout, i.e. if you have not been active on the website in the past 5 minutes, you are no longer considered online.
You can get information about the user who requested the page with variables like $_SERVER['REMOTE_ADDR'] or if you already have an authentication system you should be able to pull a users username, store this info in a database with the username/ip as a unique key with a timestamp, and simply not count them as online if their timestamp is older than 5 minutes.
You could probably use jQuery- ajax, unload and load. The ajax request will trigger on load telling you that they are viewing, and trigger on unload telling you they are no longer viewing. The rest is left to you to figure out because it sounds like you already have a grip on it.
Note. same result should be achievable in plain JS. Such as, onunload. Google will find you the rest.
I'm working on a simple PHP application, using CouchDB and PHP-on-Couch to access some views, and it's working great. My next step is to introduce Ajax to update the frontend with data from the database.
I understand you can use the _changes notifications to detect any changes made on the database easily enough. So, its a matter of index.html monitoring for changes (through long polling), which calls loadView.php to update the page content.
Firstly, I hope the above is the correct method of going about it...
Secondly, when browsing to index.html, the page seems to never fully load (page load bar never completes). When a change is made, Firebug shows a the results as expected, but not any subsequent changes. At this time, the page seems to have stopped the infinite loading.
So far, i'm using jQuery to make the Ajax call...
$.getJSON('http://localhost:5984/db?callback=?', function(db) {
console.log(db.update_seq);
$.getJSON('http://localhost:5984/db/_changes?since='+db.update_seq+'&feed=continuous&callback=?', function(changes) {
console.log(changes);
});
});
Any ideas what could be happening here?
I believe the answer is simple enough.
A longpoll query is AJAX, guaranteed to respond only once, like fetching HTML or an image. It may take a little while to respond while it waits for a change; or it may reply immediately if changes have already happened.
A continuous query is COMET. It will never "finish" the HTTP reply, it will keep the connection open forever (except for errors, crashes, etc). Every time a change happens, zoom, Couch sends it to you.
So in other words, try changing feed=longpoll to feed=continuous and see if that solves it.
For background, I suggest the CouchDB Definitive Guide on change notifications and of course the excellent Couchbase Single Server changes API documentation.
Is it a good practice to store error messages in SESSION? For example after a redirect. Passing in through url isnt a solution for me...
I am wondering if it is a good solution... because..
Would a concurent submit of user cause problem? (A long time-taking post, while ajax content is obtained from another tab) that may mess up the session! Or that is impossible to happen?
If user makes a request and it fails for some reason to display the page then the message may be shown at an irrelevant page!
So? Any alternatives??
For example when using POST/redirected/get pattern
When storing error messages in the session, you must take care, that two request dont overwrite the other ones message, before it is displayed. And you must take care, that a page, that should display a message, only displays its own message.
You should show errors, when they occur and not redirect before. Also there is no reason to redirect in such a situation.
Is it a good practice to store error messages in SESSION? For example after a redirect.
Not in general. Session data should be data that matters for a significant period, errors are generally a result of a single request and the details don't need to persist.
Storing that sort of data in a session is just an invitation to race conditions.
why dont you assign them an specific id like error_id=2 and send them through url?
or is this also not possible in you case?
you could also send an error id through session...
It is not uncommon to store error messages in session, especially in cases where there can be multiple redirects. Zend framework has something like flash messenger which kind of does that.
Anything that is in session would stay in session until you destroy it or session times out. The best practice is store the error messages in session, then when the page is loaded where the error message needs to be displayed, your code would get the messages from the session and display them if they exist. After the error messages are displayed you would need to delete them from the session, otherwise each time the user goes to this page they would see the same error messages popping up again and again.
The best approach is to display and delete.
I believe you should not run into any problem ever if you use this approach. The reason is that if an incorrect form is submitted it would always have errors in it and it will always try to store those error messages in session and display them accordingly does not matter how many times they have added/deleted in session. I hope this all makes sense.
Also when you store session error messages you need to store them smartly so that the backend knows that these error messages are stored for which form.
Focus on the user! All your development efforts want to provide the best UX possible.
The first question is, why do you need messages at all?
In case of a successful request, you want the user to know that his request was successfully executed.
In case of an erroneous request, you can distinguish: if the request may be altered by the user to turn into a successful request, then show a helpful error message (e.g. a simple form submission). If the request may not be altered by the user, be as informative as possible why the request failed (e.g. "Couldn't execute as service XY is not available. Please contact support etc.").
Easy: Erroneous request that may be altered:
In case of an erroneous request where the user may alter the request, don't save it in the session and directly render the page where the user may correct his request.
Difficult: Successful request or erroneous request that may not be altered:
Here you may generally want the user to not be able to execute the exact same request again after hitting F5 or taking similar actions, hence you redirect the user. In this case I personally favor the solution with a flash messages component (see Symfony Docs or Zend Docs for an example). In general, this technique does not lead to race conditions if your applications meets these assumptions:
Your HTTP requests fired from the browser are executed fast. A user does not have a real chance of firing a second request in the meantime.
Your AJAX calls either do not influence the flash messages - or, if you return structured data (XML, JSON) you may include a special section for flash messages, that are then being rendered by Javascript.
Now, to minimize error rates you can do the following:
Store the timestamp when you added the flash message. Don't display old messages (e.g. > 1 minute). A mobile user may loose connection and then retry. What state does he expect the application to be in?
Don't ever let the HTTP requests between your user and your server take long. If you need to perform long computations, try offloading things to a background worker and show the status of processing to the user.
Summing up: If you have general good practices concerning your HTTP communication in place, then the user is unlikely able to mess up flash messages. Weigh the pros and cons and focus on the user, not the complexity of your implementation, as there are methods to cope with that.
Generally speaking:
Try to put as much on the client-side (javascript and cookies) and try to store as less as possible on the server-side.
This includes the SESSION variable, which in the best scenario should contain only user id.
If the message is after redirect, you could add a request variable that could index the message and to show it that way.
Instead of storing in a session, you could pass an error code in the URL that you would then use to look up the error. I've user bare-bones exception classes for this kinda thing:
class MyException extends Exception
{
const USER_NOT_FOUND = 'The requested user was not found';
// ...
}
Then your redirected url would be something like /controller/action/error/USER_NOT_FOUND and you'd use that to look up the message:
echo constant('MyException::' . $error);
You don't need to use an Exception class for this, but it allows you to keep things really tidy
if ($errorState) {
throw new MyException(
MyException::USER_NOT_FOUND
);
}