I've created a small jquery and php chatroom with some .get and .post functions and php docs that read and write data to a sql server. It works fine, but the small problem is when someone posts something, it takes about half a second for it to appear (because of the lag).
I fear there's something wrong with my coding.
im using
setinterval (listen, 300)
as my continuous jquery function for reading new db entries, listen is a function with a .get inside. How does stackoverflow or facebook do it so that the user types something in and immediately it pops out?
Maybe try displaying the inputted chat message immediately to the user who posted it, prior to posting it to the database.
Like this:
User enters message, submits
Update users chat window so they see it immediately
POST message to database
GET from db and update all chat windows
This can be implemented using various techniques, which have many names: Long-polling, Server Sent Events, Comet, WebSockets, and others.
Basic idea is this:
Alice opens facebook. Her browser makes a request for updates ($.get, for example), but the server does not respond if there are no new updates and the request remains in 'waiting' state.
Bob opens facebook. He decides to comment on Alice's wall. His browser posts his comment to the server ($.post).
The server accepts this post, handles it properly (saves onto Alice's wall, etc)
But ALSO server checks if there is a waiting update request from Alice. If there is, server renders info about this update into response stream and closes the connection.
Alice's browser finally gets a response to this long hanging request and happily draws a red "1" in the notification area. It also immediately opens another update request (to not miss any).
Alice sees comment from Bob, which was delivered instantly.
The technique described is called "long polling" and it was first introduced by Google in Gmail.
You can use HTML5 sockets, however these are very much in their infancy and not widely supported (i.e. by IE).
Lots of systems use Flash as a middle-man as that can hold a connection open.
With either of these you can use your PHP code that stores the comment to the database to also push this out to every "listener". This will be the quickest way possible. If your system is super clever it'll incorporate all three - HTML5 sockets where it can, Flash where it can't, and your regular polling were there's no Flash either.
http://pusher.com/ might be a good starting point for further learning.
Most sites that have fast chat use a technique called comet. You can read more about it here: http://ajaxian.com/archives/comet-a-new-approach-to-ajax-applications
It essentially is a piece of modified server software that waits to return a response to the user until either a message is sent or it is about to timeout.
Related
I have an php framework which supports me building websites and allows me to edit the content directly in the frontend via inline editing. I have kind of an api, which receives the updates via an ajax call.
So far i was the only one using it, but in the future there could me more people editing the pages the same time, so the page has to be locked for other users the moment someone starts editing (maybe displaying which people are viewing the page at the moment as well).
I have some experience in php, javascript and a rough understanding of http requests, node.js and so on, but I am not an expert.
Now I would think, that i simply had to setup up a websocket server, tell the websocket server, when a user is viewing and editing a single page and update the page for the other clients and lock the editing buttons via javascript. So the Page would be only marked as locked on the websocket server.
Maybe I could check the status of the page when updating the content of a page by sending another request to the websocket server, if the page is locked. Or should i update the database directly through the websocketserver and mark the page as locked in the database?
Can you tell me if I'am on the right track or if it's a completely wrong approach?
PS: Even if it may be an overkill I still would want to try it only to practice, as I haven't used this technology so far :)
The approach that I would take is as follows:
Problem: (restating to show my understanding)
Notify clients when content is being edited to prevent conflicts.
Hard requirements:
Implemented using WebSockets -- for educational purposes.
Assumptions:
Sending the edited content will continue to be done via AJAX calls.
Clients do not need to know about content on pages that they're not currently viewing.
Clients should learn about the lock status of content once the page is loaded, before (or at least as soon as) the ability to edit content is available to the user.
It may become a requirement for all clients to be notified that contents on a page has been updated so that they can request an updated version through AJAX calls.
Multiple pieces of content may potentially be edited on a page, and locks should only apply on a per-content chunk basis, not a per-page basis. (I.e., a page that lists 10 customer addresses, if editing 1 address, let the other 9 be available for others to edit.)
Approach:
Personally, I'd use a PHP-based WebSockets server, but that's because I'm biased towards the one I wrote. Because of that, I'm going to approach this answer from a PHP-WebSockets perspective, and I apologize for any server specific implementation details that might not translate. That being said, it is far more important for you to use the tools that you're most comfortable with than to use a tool that I recommend, and I am trying to write in as general terms as possible.
Client JS:
On connecting, send the URL of the page that is loaded.
On initiating and completing (committing or aborting) edits, send a message indicating which bit of content on that page to lock/unlock.
Client may request the lock status of any bit of content at any time.
WebSockets Server:
On new connection, store the URL that they're on. (The same user can have multiple pages open in multiple browser tabs, but the client's page to socket relationship should always be 1-to-1.) If the page has content that is locked, send that connection a message saying which is locked.
On a new lock, store the URL, client, and which piece of content is being locked. Send a message to all clients who are registered to that URL (including the originator, who will use that reply as confirmation) on what content is now locked. If desired, store the lock status in the DB.
On removing a lock, remove the record for the URL, client, and which piece of content was locked, sending a message to all clients registered to the URL, and clearing the flag from the DB. Leave room in this method to poll the database/framework on whether the content was changed or not, to potentially tell the clients registered to that URL to invalidate their view and fetch fresh content.
On a query about any locks, respond with all locks that currently exist for that page.
On client disconnect, remove any locks. If locks are removed, notify all clients registered to the URL. If the user re-connects, it will be on a separate socket so they'll have to establish a new, different lock anyways. Clean up the connection details as well (no need to try to send messages down a pipe that's closed, right?).
I successfully send data from Android to PHP and store in MYSQL database.
What I want is to display the data in my PHP page automatically without refreshing the page when data has been sent from and Android device.
Is this possible, possibly using jQuery with AJAX?
Please explain how it can be done or point me to a resource where I can find such information.
So you essentially want to update the page when data changes on the server.
Two main options come to mind:
1. Ajax poll
Use setTimeout in conjunction with an ajax call to periodically call the server and see if anything changed. You already mention jQuery, that's certainly a good place to start. Get familiar with http://api.jquery.com/jQuery.ajax/. This is probably going to be your best bet.
2. PubSub
I use http://www.pubnub.com/ on one of my sites for this very purpose. The browser subscribes to a pubnub channel, and the server publishes on that channel anytime something changes on the server. This is obviously more work to get setup up front, and more applicable for rich client-side applications (mine is a single-page app).
There are plenty of other implementations of PubSub as well.
I have a textArea in which the conversation from all users will be displayed.
When a user types a message and clicks send button, I want it to be displayed in textArea of all logged in users without use of database/file. I want it to be done using AJAX and PHP only.
function send1()
{
req.open("GET", "process.php?q="+document.getElementById("msg").value, true);
req.send();
}
It would be simpler to use WebSockets, but if you use AJAX, save your sent messages in the DB or a file and organize the client side to read this content every 30 seconds for example, also you should maintain in your db / file only the last 50 messages, if a new message is added, erase the first one. Try to understant how the server and the client side works, then think the model of your application, on paper.
You'll want to use sockets to subscribe to a channel of messages. Ryan Bates has a great gem for Ruby on Rails that takes care of launching the channel server and the security issues that PhpMyCoder brought up.
Check out the private-pub screencast for a setup guide.
If you're not worried about storing anything in a database, you can use node.js. Here's some sample node.js code
Is there a way to detect whether a user is disconnected from internet or not? The way that stackoverflow does when you want to post a question. I couldn't think of any approach to do that. Could someone shed some light on the subject?
You can send AJAX-request to PHP script when windows is closed:
window.onbeforeunload = function(){
// Request goes here
}
Alternativly you can use websocket-technology (you can use phpDaemon) to connect with server permanently so you will know when user is disconnected from internet or your site or pereodicly (use setInterval function) ping your server.
I guess Stack Overflow uses AJAX, which is a JavaScript driven program executed on the client side inside your browser. This ajax setup is responsible for notifying the user when, for example, a new answer is posted, and giving them the opportunity to load said new answer without reloading the whole page.
And this construct has a way to detect errors in the communication with the server which it is interpreted as the user being disconnected, resulting in a warning.
However, this requires that the user is still having the browser open. There are also various other functions in JavaScript and AJAX to execute something when the user is closing the page, but neither of them are considered to always work. There are no silver bullets after all.
From the server's side, one can monitor the constant ping-pong of the user client's AJAX and execute something when this ping is fading away. Like: the user has been pinging us in every 5 second in the past two minutes, but now this ping is missing.
The main problem with this lies inside the principles of PHP and that every pages basically lives on its own. When the request is get, the page is loaded and created, but at the end of request, the current page instance is denied from existance, just like how every variable is lost which is not saved elsewhere (cookie, session, database).
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.