I have a question for anyone with experience in dealing with complex coding in PHP, Jquery and SQL. I realize I wrote a lot but I wanted to be detailed. I have an issue with 1 solution that I can think of but it doesn't seem very efficient, especially with large amounts of traffic. I have a table that stores messages from users. I am designing a chat platform where users can open a chatbox and send instant messages to other users who are their friends.
I need the ability to have it so when a user opens a box from his online friends and sends a message, that friend will have a chatbox pop up with the message or messages and the box will update from there. I would like that box to also maintain the previously sent messages in it from page to page when the user is navigating the site until he closes the box. When this happens, I created a viewed column which I can mark as 1 for all the messages that were in that box at the time. From then on those messages will not pop up. Only new ones will. So closing the box essentially resets it.
I have a simple JSON function where information is sent and a php handler runs a query and returns all the messages. They are then sorted into their boxes.
What I think is one solution is to put a refresh time interval on the json code and check for messages constantly where viewed=0. If there are and the box has not yet popped up, it will and have the messages html'd into the boxes. The problem with this is that the query will be selecting all the messages that the user has received and they will be constantly overwriting the boxes which won't show visually but seems taxing on the system. I was trying to think of a way that involves a query that checks for timestamps that are greater then a timestamp sent in the jquery function. IF anyone has any recommendations or useful articles or information, I would greatly appreciate it.
$.getJSON("../collabrr/chatbox.php?action=view&load=initial&receiver="+username+ "&token="+ token, function(json) {
for(i=0; i < json.length; i++) {
openchat({ data : { user : json[i].user }}); //makes chatbox open up with name of sender
$('#chatbox[data-name="'+json[i].user+'"]>#messagebox').prepend('<div id="chatbox-response">'+json[i].user+':'+json[i].message+'</div>').find('li').fadeIn(1500);
}
});
$sql = 'SELECT timestamp, user, message, receiver
FROM chatbox WHERE receiver=? AND viewed=? ORDER BY timestamp DESC';
$stmt = $conn->prepare($sql);
$result=$stmt->execute(array($_GET['receiver'],0));
}
Field Type Null Key Default Extra
id int(6) NO PRI NULL auto_increment
convo_id varchar(35) NO NULL
timestamp int(11) NO NULL
user varchar(25) NO NULL
receiver varchar(25) NO NULL
message varchar(150) NO NULL
viewed int(1) NO NULL
Polling the server for updates is one solution. I can give you another one, however I dont know if you have the resources availabe/the time to implement it.
In very short, this is what I did when I implemented something similiar: the basic idea is to use Websockets and keep a socket open to a backend. Preferably node.js using socket.io because of its non blocking nature. Then you would use redis and its pub/sub capabilities to receive updates from client A and push them to client B.
When client A loads your website, it connects via a Websocket to a running node.js process, call it PUBLISHER. Publisher subscribes itself to a specific channel in redis for this client. Client B loads your website, it also connects to Publisher etc. just like client A. Now client A writes something and it is sent to Publisher. Publisher publishes this event to its redis channel. Client B gets noticed, because he is not only subscribed to his channel, but also to A´s channel (maybe because they are friens on your social network site if you have one).
This sounds probably rather complicated, and it is not that easy to implement, but maybe this can give you a basic idea about how such a pub/sub system is implemented. Polling should only act as a fallback solution because on a high traffic website constantly polling your webserver with ajax requests every 100ms or so will cause extreme load.
It sounds like what you're wanting is an Ajax push solution (also known as 'Comet' for some unknown reason).
Here is a site which explains how to do it in PHP/Javascript: http://www.zeitoun.net/articles/comet_and_php/start
See also the wikipedia page: http://en.wikipedia.org/wiki/Comet_%28programming%29
(heh, I note that also includes an explanation of the name 'Comet')
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm working on a college project where I have to made a chat that contains invitation options with ACCEPT/REJECT between registered users only. If an invitation is accepted, then open the chat otherwise send a message to the sender.
I've completed the whole project except this invitation option. I know that I can use COOKIE for this (with setInterval), but I need something more secure idea to do this.
In my current PHP invite function, (for example: invitation sender: a#a.com, invitation for: b#b.com) I used to verify the b#b.com user (registered or not) and send back the JSON with verification. If user is registered, then open a chatbox on self-end only (a#a.com) and can send message to b#b.com. The b#b.com user will only gets these message when it opens the chatbox with invitation sender : b#b.com, for: a#a.com.
I have no idea to how to send an invitation directly to b#b.com with option and get back the clicked event (accept/reject) to `a#a.com.
Currently there is a single idea in my mind: cookie with setInterval. But there is a demerit of this idea is, both users page continuously checks the cookie, it means more load on bandwidth and more process on user-end and most of all, it's not secure.
And I'm already user 3 setInterval functions into my project : status check, new msgs check and chat options.
So, can anybody suggest a better approach?
This is rather a broad question, but I'll try to offer some basic design guidance. I expect that a user will enter their email address and the email address of the other person, and click on a "log on" button.
What happens next depends on your design, but this is what I would do. This involves AJAX operations, which is fine for the purpose.
The details are submitted to the server, and a row in a user table is created. The user gets an ordinary session cookie by default, so you just need session_start at the start of each page. A row in a conversations table is also created.
We'll assume that the user is now in a connected but not chatting state.
Using jQuery or similar, a call is made periodically to the server to see if the application status from their side needs updating. To start with, this will determine whether the other user is available. Let's say this call is made every 10 seconds, to avoid excessive load, and every time a call is made, the user table is updated with a last_seen_at timestamp.
You run a script on your server that examines live conversation rows and sees if both parties are online. If they are, and the conversation is not marked as started, then update the row and then notify the users when they next request an update.
When your browser application receives a notification of some kind (in the reply to a periodic AJAX request) it will need to redraw its screen. The life-cycle is: start -> log-on -> waiting -> chat -> log-off. You'll need to work on the JavaScript to do this.
Some of the fields in my suggested table structure below are used to capture the state of the chat, so your PHP application doesn't have to remember things itself. For example if conversation.accepted_by_user_id is null, the conversation is waiting for the second user to accept the chat request. If message.received_at is populated but message.sent_at is null, it means the message needs to be transmitted to the second user when they next send an update request.
Where users or conversations get too old, they can either be marked as stale or deleted entirely.
Side note: we have made no attempt to check that the users own the email addresses they have specified, or whether they even exist. But, for the most part, it doesn't matter - all we need is for the two parties to have a unique string that they can both remember.
Suggested tables:
user (
id (pk) int,
email varchar, // user's email address
email_to varchar, // the email address of who they wish to chat to
session_id varchar,
last_seen_at timestamp
)
conversation (
id (pk) int,
started_by_user_id int, // foreign key
accepted_by_user_id int, // foreign key (null if not yet accepted)
from_notified_at timestamp,
to_notified_at timestamp // timestamp (null if not yet accepted)
)
message (
id (pk),
conversation_id int, // foreign key
is_forward boolean, // true = a->b, false = b->a
message_text varchar, // actual text of message
received_at timestamp, // when it was sent in a server message
sent_at timestamp // when it was picked up in a server message
)
You were worried about the security of cookies. If you use session cookies it means that only the user that initiates a session can use the session ID given to it by PHP (there are a couple of exceptions: the theft of a cookie by a malicious third party via script injection or the capture of data by eavesdropping. You can use SSL and read up on XSS if you are worried about those things, but I would say it is beyond the scope of a college course).
Long story short, you've chosen a non-trivial project! Good luck with it, and if there is something you don't understand, break it down into a smaller pieces, until the pieces are each programming problems.
Now, you can do this project with sockets, but you should learn to walk before you start running. I would suggest you try it this way first (since it is easier but still hard enough) and then if you can do that, move on to sockets.
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?
I want to build a simple message system between my users of my website. For that i constructed table for messages as below:
tbl_messages
-pk id int
-fk sender_id int
-fk receiver_id int
-is_read boolean
-send_date datetime
When a user has my site opened in the browser and some other user sends him message, i want to send a notification message to the receiver user (something like 1 new message or (3)Messages) while the page of receiver is opened.
Eg: facebook notification, stackoverflow notification comes when new comment arrives
I performed such action by making a javascript function to be called every 2 min. This function makes an ajax request to output the notification. I wonder is this the correct and effective way to do because i have to perform the sql query every 2 min and if there are lots of records in my table, such action will create more load on database.
What other solutions can I perform instead of this?
If you correctly indexed your database and designed your program, it shouldn't be a problem.
You won't be able to design a notification system as responsive as Facebook and other, since it's almost impossible to create push systems with PHP.
If you have a dedicated/virtualized server (and not shared hosting), look into things such as NodeJS.
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.
I want to learn how to make one of these systems from scratch and I'm find a lot of junk links on Google. I really just want a simple tutorial for the most basic PHP and MySQL chat so I can understand the concept before I start messing with jQuery/AJAX.
PHP/MySQL chat 101:
1) user opens a browser
2) user enters address in brower
3) browser sends HTTP request
4) server recieves HTTP request
5) server tells PHP interpreter to run PHP script
6) PHP script connects to MySQL database
7) PHP script retrieves list of messages
8) PHP generates HTTP response made of HTML code with messages and form
9) Server sends HTTP response to browser
10) Browser draws HTML from HTTP response
11) User types new message and submits the form
12) Browser send HTTP POST request
13) ...
A very simple starting point
Have a database table for a Message
id | user | timestamp | message
And have a PHP page that sends an AJAX request to read any new messages.
This will involve checking the database to see if there are any messages since the time the request was received. If no messages, then loop, wait and try again in 100ms (or whatever you think is acceptable lag).
When the Ajax request returns a message (a JSON response would be best), output the user, time and message to the page using JQuery.
The live part of your chat is the tricky part, if you are just beginning i would skip that.
Start by building a simple guestbook, and then add more features.
There are many tutorials available on how to build a guestbook, and even some free scripts where you can learn from.
After you got your guestbook working, you could add features like auto-loading new messages to make it appear as live, using AJAX polling. What you basically do make an AJAX call to the server at a regular interval to get all the messages and display it on your page.
Found very interesting tutorial here
http://tutorialzine.com/2010/10/ajax-web-chat-php-mysql/
If you must use php and mySQL for chat, atleast have a seperate table for unread messages. If you poll you will most likely need to check the database for new messages every 100ms or so. If your total message table is 1000 rows checking every 100ms will kill your server (especially if many users are connected). I would structure my mySQL database with a table for only unread messages and move them to a bigger table for old messages once read. That way your not checking a big table all the time.
Even better is to use a cache database for unread messages like redis (facebook used memcacheD).
Even even better is to just not use php all together and use an event driven language with callbacks like node.js