PHP AJAX - Chat functionality - php

I'm building a web application using PHP, JavaScript/jQuery and MySQL. Right now I'm trying to implement a chat feature that allows two user who are both online to chat with each other (e.g. NOT a big chat room, but only private chats between two users). However, I've ran into the following questions during the implementation process:
How can I let one user know whether another user is currently online or not? Now I have a page where a user can see the name of other registered users. I hope to differentiate those who are currently logged in from those that aren't. Currently, when a user is logged in, I store his username in $_SESSION['name']. So how can one user know whether another user's $_SESSION['name'] is also set?
How can I ensure that the conversation is private to two users? I currently have a page called "chat.php", where the chat interface is located in. When one user clicks on the name of another user who's also online, the two will be directed to their own "chat.php". Similarly other users should be unable to view chat that they are not involved in. I'm currently thinking about generating a unique page for the two users, like "chat.php?user1=Tom&user2=John" But how exactly should I achieve this? I'm new to PHP.
To display the new message if the other person has just sent one, can we do this using Ajax in an event-driven way? Or can we only use polling? I'm currently using polling like the following, but I feel that polling isn't every efficient:
// "logs.php" reads chat message from the database
setInterval(function(){
$.get("logs.php", {}, function(resp) {
// display the response
});
}, 1000); // poll every second
Any input to any of the above questions is appreciated! Thanks.

I am also currently working on chat right now, below answer are according to my best of knowledge if you find something wrong please comment it.
Answer 1//
With the use of session you will not be able to get who are logged in and who aren't, to check you have to set flag in database and from there you to fetch logged in user apart from current session user.
Answer 2//
Here you are mixing to different concept of chat i.e. one to one chat(private chate) and another is group chat. What I will prefer is create different chat file for both concept.
Consider a scenario where you 100 user chatting in group you will not be able to send 100 user id through ajax.
Answer 3//
Long polling is the method with which you can achieve real time chat update. But still there are so many catch to use long polling with PHP. First and foremost is the main drawback using long polling is it use more resource when user will increase.
So, in conclusion try to use web socket programming or use different framework like node.js to implement.
If you have less number of user then definitely you can use long polling with PHP.

Related

turn based game with ajax and php

I develop a turn based game and want to put up to browser to test with real users. because it is a turn based game I don't need it to be real time. my idea is using old school chatroom method to set text to communicate between 2 players. after much testing and reading, I found this site provide a relative decent guideline and I tested it on my server. However there are 2 problems that I don't know how to do:
How do I keep the communication between the 2 specific players? I imagine if this is chatroom, every time a player start a game, it is just like start a private chat room and only allow another player to join in. How can I do that? I need to understand the methodology to be able to work around the code.
if ever any of the player offline, how can I ping the other online player?
Your question 1, seems to be a matter of validation.
You should just validate that a game is on-going between user1 and user2.
Assuming you have a game table, you just restrict access to the page.
You should probably have a chat-game tablet as well, if you're keeping history.
Your question 2, you have a page that is constantly flushing and updating the chat, you have access to the user session\cookie. Seeing as this is a 2 player-game, when you send out information, you set a flag, of last-received per used, if it's between longer then a minute, between one user receiving, just update the response, so that the user gets that information as well.
When the user comes back, just grant him access to the page again, using gameid, or something of sorts.
Actually not that hard.

Loggin a user out of a database on browser close PHP/MySQL

I have seen MANY questions on this before online in many places, however, out of about 30 forums and whatnot, NONE of them have had the solution I need, and that includes stackoverflow. If anyone could help me find a reliable solution, it would be greatly appreciated, so thanks in advance!
I'm going to explain my site and situation with as much detail as possible in order to help any who want to help answer my questions. Here is my situation:
I have a website and I use PHP and MySQL. My website is a "private" organization site. In order to allow people access to the site, I send new members of our organization and invite code. The user then visits the website, and the index.php file simply contains a form for logging in as well as a link to the registration pages. New members click the "Register Here" link to begin registration. The first registration page asks for the user's last name and invite code which are checked against a database to make sure that person is on the list and has not yet registered. If they pass the check, they are taken to the next page in which they enter required information (username & password, email address, etc.) as well as some optional information (phone, bio, etc.). If the user creates a valid username and password and has all required fields filled out, their information is stored in a database. Passwords are all salted and hashed properly and securely, so there is no problem there, and the whole registration process works as it should. After registering, the user is taken back to index.php where they can now log into using the username and password they just created. This works as well; when the user logs in, their username and password are checked against the database, and if successful, the user is logged in. When the user is logged in, an ONLINE value in the database is set from False to True. The user is now logged in and can use the site as it is intended. On my site, there is a column that lists users that are currently online (based on the ONLINE value from the database). When the user clicks the "Log Out" button which is located on every page of the site, the logout.php script is run, ending the session and setting the ONLINE value back to False. This all works fine and dandy, however, the problem comes when the user closes the browser without logging out first. This is where I have seen many different "solutions" various places on the internet. I am going to explain why they won't work and why I need a better solution.
The answers I see most often involve some sort of session timeout or destroying sessions, which is irrelevant because of the fact that the session already does, in fact, end when the user closes the browser, but that has no effect on telling other users whether or not that person is currently online. When the session ends, the database won't be updated, which causes a problem due to the fact that a user can only be logged in from a single instance. If a user attempts to log in while their ONLINE value is already set to TRUE, they aren't allowed to log in.
I have also seen suggestions of using a "Last Seen" value instead of an online value, and if a user hasn't had any activity within the past x amount of minutes, log the user out. This won't work, however, for two reasons. 1) That script still has to be running somewhere in order for that to work, meaning another user must be logged in for that to work. That basically means that, if using this method, if a user closes their browser or if they loose connection, they won't be able to log back in until another user logs in. With my organization being a small, locally based organization as it is, there are likely to be many times in which there are no users online. Also, even if another user is logged in, the user whose connection was lost still won't be able to log back in until after x amount of minutes has passed, so if the user accidentally closed their browser and wanted to log back in immediately, they simply wouldn't be able to.
A less frequent solution I came across involved using the onBeforeUnload JavaScript function, but those most definitely will not work due to the fact that those would trigger any time a user clicked on a link or on the "Back" and "Forward" buttons. Also, if the user has JavaScript disabled in their browser, this will not work at all.
The last thing I have seen involves while loops and the connection_aborted function, and this is the only one that seems like it could work, yet I have not seen a very clear description of how this should work, and after spending months experimenting with it, I still have not come up with a reliable solution.
In many forums, I have seen people say that "it's not possible," but that can't be the case considering there are sites that do it somehow. I have tested and experimented with this on several sites. On a site that has users such as Facebook or any forum website, there is a list of "online" users, and in the case that a user closed their browser, their name would no longer appear on the list, so it is possible, even if it can only be achieved through some obscure method. So, if anyone knows of a solution, I would greatly appreciate if you could share some of your wisdom on this subject!
Try creating a Heartbeat mechanism in javascript.
this method would start sending an ajax call to your webmethod on timely basis use.
setInterval(function(){
sendPulse();
},30000);
sendPulse(){
var varUserID = userID;//any unique user identifier that can be found on server side
$.ajax({
url: "Default.php/updateUserStatus",
UserID: varUserID,
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (mydata) {
//alert("pulse sent");
}
});
}
On server side, you must have a method with same name and case sensitive parameter. the should be static and marked as webmethod. in this method save the current time for the user. you should have a mechanism to know what users have very old pulse, do this check when a user tries to do something or performs any operation. I have implemented this approach and works very well.
That's the answer: persistent connection between client and server. For this, you will need a TCP connection, like websockets nowadays, or a flash old duplex connection. From here on, TCP takes care of noticing you when someone connects or disconnects. What you got to do is a websocket server (for example) who just traks connections (push and pop from an array), and also a way to respond to a "get_users_online" message. You can access your user's session (read only) via the websocket server, and then see if the user is logged-in (and in this way, you can store his nickname in session, access further from websocket server), see if he is admin (session->is_admin).
Pretty simple, I would say.
Here is the library I've been using: http://socketo.me/ . It uses a library for decoding symfony2 sessions, but for simple applications, you don't need decoding (symfony2 applications encodes sessions, so the websocket server has to decode them).
Big note: Sessions has to be stored externally (not in file system /tmp) like a ORM or NoSql.
Either way, escuse me, but I have to say that that the "Last time" seen is super okey. Most of the sites rely on this. You understood something wrong, you don't need to have a living server for checking "Last time" always, when you request /admin.php?users_online=1 , you make a query where "Last seen > NOW() - 5 minutes" (won't work written like that), so you can even get rid of the "ONLINE" "OFFLINE" field.
I suggest using a websocket approach, it's fun. :)
Good luck!

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?

Model PHP/Ajax Notification System?

I'm making a website similar to Facebook - with things such as Notifications which make it similar. I don't really see how I can get notifications working. Well, I figured out how I could get them from the database, with a query.
The structure I think the site will follow would be multiple tables for different applications - ie: Photos would add in an ID for the picture, a filename, and a few user IDs if 'tagged' or something, and how to send that information to the user in real time.. is beyond me.
So I would have to run several queries every few seconds scanning the database tables for the $_SESSION['id'] of the user being found in all the applications tables with a status of unread?
Another possibility is that every user has their own table? That's .. a lot. lol.
Or just a notifications table with the most recent notification being pushed to the table with a unique id and a user id?
I really can't wrap my head around this, lol.
Also, displaying notifications in real time? I understand Facebook uses long-polling and gets the notifications in real time, but I don't think I could leave about 5-10 queries (for each app) running on a long poll for multiple clients, or that'd completely crash my server, right?
Any advice/code on how I could try and make a notification system for a social networking-ish site? If not, I think i'll go with static notifications rather than any sort of realtime.
Then again, that'd be too much load querying the server every few seconds for a new notification on every page load? Using ajax would mean long polling, so it's a lose-lose.
I would say Long polling is the answer. Gmail and Facebook both use this method for real-time notifications. Your only other alternative is Flex with a dataservice, but that is not PHP.
In terms of performance, the query is only going to pull from 0-5 notifications at a time, and if the tables are indexed properly, and the query is written well, then 5 of these queries will not be a significant impact on your server.
Furthermore, if Gmail and facebook are doing it, then it stands to reason you can also do this. Granted, they have a ton of servers to support all their users, but I am going to go out on a limb and say you don't have as many users as they do, so as a result the server technology will work for now. And when you get so many users your current servers can't handle the load, then you invest in newer more powerful ones.
Well here is my take on it.
You could create different tables for status, photos and videos.
Everytime somebody comments on a video or something you can do the query to store the notification along with the information of the user who liked it, you should set a status field too, so you can query based on which has been seen and which has not been seen by the user.
You can put the url of the page where the photo is or status is located so when the user is logged in you do a query every five minutes checking for unread notifications, if there are any you display them in a tiny toast message on left bottom side of the screen like facebook.
On click of the toast message you can do an ajax call to update that status of the notifcation to read so it does not show up again and in the success call back you can take the user to the page where the status update is.

Storing a "Users Online" list for a chat application (php/ajax)

I have several chat rooms. Currently, I store the list of chat users in a php variable. If a user enters or leaves the room, the user's name is added/removed from that list.
To make this storage persistent, I use memcached. To update the status of the chat room and send the user list to all users in the chat room, I use periodical ajax requests that fetch the user list into the browsers of the users who are in the chat.
It works okay. But I doubt that sending the whole list of chat users to everybody every XX seconds is a good idea if there are a couple of hundred people in the chat.
How are chat rooms usually dealing with this problem?
Have no idea how they do, but here are some ways you could. Remember to measure before and after you optimize.
Version the list. Don't get the full list if you have an up to date version.
Diff the list. Send only the updates since the last update.
Log this list. Cache or push updates as new events occur.
The way I run my chat rooms, I timestamp all the new messages and new sign ins and sign outs.
When a user enters a room, I download the full list.
Periodically(via an AJAX with JSON call), I will download any new events (messages, logins and logouts). And update the relevant lists accordingly.
Honestly, what you are doing sounds pretty good. Keep doin what ya doin. Maybe keep track of the last list and only send an update if they have changed in the last x time? If you really want to save a few bytes.
I would push the list updates through the same channel that the chat messages go through, too. If it's an endless-loading page, maybe you could inject something like this in the page:
<script>updateUserlist({user:"alice", eventtype:"leave"});</script>
Thanks for all the suggestions. Additionally, I will look into running a comet server.
The long-polling approach just would not scale well.

Categories