编码技术效率问题:聊天室设计

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')