Event triggering in server-side scripts - php

In SO, when your question got answer. or you got new badge, event is triggered. Or when you got new PM in forum, it also lets you know by alerting message.
You see message that something happened with your account when you enter site for first time after this event.
How is this implemented? How do scripts know, that they have something new to show you?

The programming technique you are looking for is called Comet. The link to wikipedia describes some implementations of that, but the easiest way is to make an XMLHttpRequest with a long timeout and only return data on change.

As an answer to your last comment
There are several tecniques to mark events as a 'new'. It can be another field in the database table, of boolean type: telling if event was shown to user or not. Or - easiest one - just a time of last user's visit being recorded in the session, and then al upcoming event's time being compared with it.

The event happens when another person does something like vote on your answer or question. This is recorded on the server side.
When you log on to the site the fact that some events occured while you were away can be determined from looking up the database for these records.
While you are on the site it is possible for the page to periodically poll the server for changes. So its not really the server that the event is triggered on.

Related

Having a variable which is same for all the clients of the site in PHP?

I am creating an event in which if one user submitted the problem correctly all the users will be forwarded to the next question. For this, I have implemented by storing a variable in the database for knowing if the solution is submitted or not. Problem is that Like 100 people will be playing the same event at the same time so for all the users we have to check repeatedly in the database that is the problem submitted or not which kind of seems hectic.
Is there any better way to implement this like having a variable which is common to all the users?
You could use ajax in your client side to check for updates every 5 seconds.
When a user updates the correct answer you can store the answer in a cache like memcache / redis. The function the ajax request triggers will see if there is a answer in the cache, and it will return true. In your client side JS you can check if the returned response of the AJAX was true and then proceed to the next question.
So for example you will send a ajax request to /getupdate with a ID of the current session or similar, the /getupdate page will execute a function which will look for the ID in the caching server, if the ID exists it means the question is answered so it will either return TRUE or the value of the answer. In the client side, you can check if the value is FALSE and if it is, don't do anything, if they value is not FALSE, you can have the next question updated, or show the answer to the user.
You can make use of Web Sockets(like Ratchet) and broadcast to the whole server. Each client connected will listen the message and you will have to define a state storing current question, meanwhile you can update the database storing the current order of question in case if anyone disconnects you can assure everyone gets the same order upon reconnecting.
Making AJAX calls will also do if you don't mind the delay between timeouts, which in your case does matter.

I need to show which users are online for my AJAX Chat

I have an inline chat application which I got from Ajax Chat, which is working brilliantly. The application allows a user to chat with users that are registered on the system. Ie:
Now I need to show if the user is online or offline.
So my question is how do I show online users using PHP?
Thank You
Basically what you need is a way to register users activity.
One way you can do this is doing it by sessions within PHP, and you log these. There are tons of ways to register then your activity in a log. If the activity is not updated for example in 5 minutes, the user is offline. Bassically you just need then a sessionId, and a timestamp (and i would recommend this also to hang to a userid). If offline, there is no userId assigned and when online you add a userId. If you have those, its pretty easy. Its a matter of updating them constantly when a new page is loaded and if they log out, you simply destroy the session, or update it so it wont be linked to the user.
It may not be the best system, but it works, and it might help you.
I don't know your specific needs. Pardon me, If I am wrong.
If Jabber support is there with Ajax Chat, why not try ejabberd kind of XMPP servers rather than re-inventing the wheels on your own. And you could have a look at Apache Vysper too, since it has support of extension modules too. If XMPP server is there, users presence handling and message transfer would become a cake walk.
What you need is a constantly update for a table in your database that save the last change in an user and save the date time... so if that date is more than 5 or 10 min, the user ir off..you can do it with ajax...
What i would do is have a script that the clients run to do an ajax call to update a entry in your database with a time stamp for last seen. Not too often or you will overload your server.
you can also put some if statements where it checks for keystrokes, mouse movement, and if the window is active if you really want to get technical and do a away status.
then in active chats just check the time stamp for active messages or when the user list is open. anything outside a acceptable range will show the user as off line. 5 minutes seems pretty long to me. poll for a check every 10 seconds maybe?

Page title Notification in multiple browsers

I have a chat script on a webpage.
Now, when someone adds a message I want to notify other people who have the page/tab open but not active, to receive a notification of a new message.
For instance, I would like to change the page title from 'Chat' to 'New message - Chat'.
I think this is what 'Facebook Chat' does too.
But when I use:
document.title = "New Message";
It only changes in the browser of the user that submitted the message. Not on the other browsers.
How can I achieve this?
You can give your title an id:
document.getElementById("title").innerHTML ="new Title";
or simply
document.getElementsByTagName('title')[0].innerHTML = "New Title";
either way it will work
UPDATE:
after rereading i made a mistake i see.
when your script check for a new message, if there is a new message you should change the title also, or perform additional test to see if there the user is active or not before changing the title
To do what Facebook Chat does, which is notify each user of updates in close to real time, you need to use "push" technology or something that emulates it. Possible techniques are polling (just having each client regularly hit the server to check for updates), Comet (long polling or streaming connections to the server), or newer and more authentically "push" (but less supported) methods like server-sent events or the WebSocket API.
Polling is not the most efficient technique but will be the simplest to implement. You could start by writing a server-side handler that accepts a timestamp, and returns a count of updates since that timestamp. Client Javascript calls that handler at an interval, passing the timestamp of the last check, and handling the response (updating the title bar if there were recent updates found).
Listen document.title = "New Message"; is an absolutely perfect code but you've put this in such an area that when a person types a message, it is executed on his page which is wrong. You should add this piece of code when the user waiting for a reply (the other user, you're chatting with) when the AJAX (or any other method you use to check) receives a response from the person who has typed the message.
Basically what I'm saying is that this code piece has been placed in the wrong place. You must place this code piece when a person received the chat message and not when it is dispatched to another person.
And then later on body, you can make event when onmousemove change the title back to the original one! So this is how Facebook Chat works.
Your mistake is the place, you've place your code piece, nothing else!
Hope this helps, Cheers!

Counting the time a user has been connected to a site

At the moment I'm using this SQL to check if a user is connected:
date_add(last_activity, INTERVAL 3 MINUTE) > NOW()
This is passive and will only trigger when a page is loaded.
What I'd like to do is a system that checks if a user has remained connected during a given span of time and give them bonus points.
What do you suggest to achieve this? Use polling or another approach?
You need to use some kind of java script that will report activity using ajax to your site in intervals of like 1 min. You need to implement some sort of mechanism to check if user is active, like if the mouse moves or page is scrolled, because some users can use the same page for long times. If the page is not used since the last min(should be a global var in javascript, set to true every mouse move, and to false every time a message is sent) you don't send a message.
When you receive the ajax notifications in the server you check the time between the last ajax notification(should be stored in database) and current notification and if its smaller than an interval (maybe 2 mins) give the user points for it.
As said you can use AJAX and alternatively the Refresh META tag. Note that if I see a browser tab constantly refreshing, I close it as it is distracting. Of course, if you're offering a service that requires frequent refreshes (chat / shoutbox, ticker) then it's less disturbing.
I currently have 14 tabs open, some of which for days which I haven't really looked at, so you gotta ask how valuable your information is. As far as I know, javascript is unable to get the current mouse position if it's not moving over something that has the mousemove event handled, so implementing "is the page in view and the user moving her mouse" may prove to fire a lot of events when user is active.
I may be oversimplifying here, and this probably won't help much if you're trying to charge for time on the site or something like that, but this is something google analytics takes care of. Time on site is a metric they actively record.
Ok. So here is my idea. As I mentioned in comment my way would be javascript timeout and AJAX.
So the idea would be something like this:
Make a global variable for mouse position.
Set timeout for function to fire in around 10 second intervals (which can grow in time).
Function compares last mouse position with current mouse position. If it has changed user is presumably active.
Update global variable for mouse position. And send data to server-side.
Rinse and repeat...
Actually thing that changed can be anything if you want, but mouse position would be most suiting I think.

How to update content based on user actions [like the facebook wall]

For my next application i would like to implement something that has a feature like the facebook wall but let me explain a bit. For those of you who used facebook you know that when somebody posts a message on your wall, and you are logged in to your account, you will get a notification immediately somewhere in the lower left corner. Lately they even pushed this a little bit further and if somebody comments on it the comments are updated as you visualize the page, it's like an instant chat.
My application will be developed in PHP, I will use Zend Framework to do it. I'm interested in the basic principle that makes the facebook wall behave like that (updates in real time). I know there is ajax involved but I can't really tell how is the javascript triggered when the user is doing something. Or even more, how to push back to a user some info that was added after he viewed the page. For example, let's say that a somebody adds me as a friend. I would like to see a notification saying "X has added you as a friend" if i am logged in. I hope you understand what I'm trying to do.
If you can tell me some basic ideas, maybe provide some links that have this information I would be very grateful.
Thank you for your time in reading this.
you need to look at comet , reverse ajax , ajax polling
If some event is triggered, then store the event on database (with ajax or without ajax).
You will be needing a script in server to check if some event has been triggered or not. This script should be able to check events that are stored in database.
You need to execute script in step 2 periodically. This can be acheived with with ajax (javascript or jquery) and a function settimeout (on javascript) to send ajax request to server periodically.
Changes are sent from server. So parse the response and update in page using javascipt and jquery.
So, it can be summarized as
Register an event (for one user)
Check the event (for other user)
Parse the response and update the page
There are several elegant ways to do this as answered by others.
The best would be the start the project and ask for help where ever stuck.
It is only partially possible to keep an HTTP connection open, so the best option is probably to poll for changes. You can send a request each second to see if anything is changed since time 'x'. On each response you send along the server time. With the new request you send the time of the old request and the server can return any events that happened inbetween.
Also you can read something about AMQP. You can send a message to recepients inboxes (after some actions in your system) and then read inboxes after start or with some time interval.

Categories