|
|
|||||
Creating a chat script with PHP and Ajax, Part 2Welcome to the second part of the 'Creating a chat script with PHP and Ajax' series. It's been a while since the previous part, and much has happened since then. 37Signals, a very popular "web 2.0" company, has released a web application called Campfire which is actually a chat script based on Ajax and Ruby on Rails, and it has many of the features we'll be implementing in this article series. In this part we'll start from scratch again, but this time we'll start with a solid structure. Unlike the previous part, which was more or less a hack job, we'll start using JSON and several other libraries to make everything easier for us. I will also show you how to add a few more features, like a user list. This article will be quite fast paced, and some things won't be explained in detail. That's why it's highly recommended you download the projects files by clicking here so it's easier to follow along. You can also view a live demo of the project, by clicking here. Let's get started with defining how our web app should look like. Our web app needs to be able to do several different things, like doing Ajax requests, using a MySQL database, and more. Instead of writing everything ourselves, why not use publicly available libraries? In our web app we're going to use the following libraries: Next up is the structure of our web app. In this tutorial, I'll be using the following directory structure: It's obvious that all the libraries are in the 'libs' directory, and all our JavaScript files will go into the 'js' directory. Finally, you will also have to create a database with the following structure: CREATE TABLE `user` ( Before writing the main thing of our web app (the chat), let's first create a few basic necessities, like a database config file, and a few other things. if (get_magic_quotes_gpc()) { return $value; $_POST = array_map('stripslashes_deep', $_POST); // Get site path // Include libraries include ($site_path . 'includes/functions.php'); // Connect to MySQL DB ?> Make sure to put your own database user, password and name in the file above, and save it as 'global.php' in the includes directory. The web app will also need a common 'functions.php', which holds frequently used functions like generate_password() and such. Click here to download the 'functions.php' and save it in the includes directory. Now that we've got the basics pretty much laid out, let's start with the actual web app. The first thing we'll do is create the chat client itself.
To start off, our chat client only needs to do three things: The HTML behind these three things is fairly standard: <link rel="stylesheet" href="style.css" type="text/css" media="screen" /> <script type="text/javascript"> <!-- JS Libraries --> <!-- Chat JS Files --> </head> <body> <div id="login"> <a href="#" onclick="login();">Enter the chat room »</a> <div id="chat" style="display:none;">
<input type="text" id="talk" name="talk"><input type="submit" value="Say It!" onclick="send_message();" id="sayit" /> </div> </body> The above page uses fairly basic HTML, and consists mainly of two div elements ("login" and "chat"), a few input elements and a list element for the user list. The page also includes several JavaScript files, including the Prototype, JSON and Logger libraries. To make the chat room look a bit prettier, an external stylesheet is used, which can be downloaded by clicking here. If you try to use the page above, you'll find that nothing works yet, because we haven't written any of our custom JS files yet. But that's what we'll do now, starting with the login.
If you have a look at the HTML in the previous example, you will notice that the login link uses a function called 'login()'. This function has to send the username that was filled in by the visitor to the server, using an Ajax request. It looks like this: // Check if username isn't empty // Send login request var ajax = new Ajax.Request(url, {method: 'post', parameters: pars, onComplete: login_handle_response}); Logger.info("Logged in: " + pars); The function makes sure a username was filled in, and then sends the request to 'login.php'. For easy debugging it also logs the information using the Logger library. On the server side, PHP has to handle this request, and return the appropriate response. What the login.php file has to do is make sure that username isn't already in use by someone else, then insert the new user, and finally return the user list. It looks like this: // Get username and generate last active and random password // No username? // Make it safe // Remove any inactive users // Try to insert new user // Unique error? (errorno = 1062) // Return success, by sending the complete userlist // Get userlist // Return JSON ?> Most of the above is fairly self-explanatory, and should be easy to understand. Please note that the remove_inactive_users() function is used to remove any inactive users, and can be found in the user-functions.php file, which can be downloaded by clicking here, and should be stored in the includes directory. At the end of the example above the return_raw_json() function is used to return the user list to the chat client. This function can be found in the common functions.php file, and uses the PHP-JSON library to send the JSON. Now that login.php has sent a response, the chat client has to handle this. When sending the original request, we actually defined a feedback handler called login_handle_response, which looks like this: // Transform JSON if (data == false) { if (typeof(data.error) != 'undefined') { // Which action? This is just a really basic function to transform the returned JSON into a native JS object, and then calls the do_login() function to continue the login process. The do_login() function takes in the data returned by login.php, shows the chat, and creates the user list. It looks like this: // Save them // Insert users into userlist // Show chat var ping_obj = new PeriodicalExecuter(ping, 1); A very important thing which the do_login() function does is creating a new 'PeriodicalExecuter' object, which is the whole core behind our chat. It's basically a timer that runs the ping() function every second, and that's the function which gets the new messages in. The do_login() function also uses the add_userlist function, which is used to create the user list and looks like this: list.each( function(user) { ul_users.appendChild(new_li); That's pretty much it for the login part, and all we need to write now is the code necessary to get new messages and any changes in the userlist. As I've already explained, a special function called ping() will run every second, and this is the function that will: It's actually a very simple function, and all it really does is send a Ajax request, like so: var ajax = new Ajax.Request(url, {method: 'post', parameters: pars, onComplete: handle_ping}); Logger.info("Sent Ping: " + pars); This request is then received by the ping.php file, which actually does all the magic. It first authenticates the user, like so: // Authenticate user Using the auth_user() function, which is located in 'includes/user-functions.php' and looks like this: function auth_user { // Get vars if (empty($username) OR empty($password) OR empty($lastactive)) { // Authenticate user if ($user == false) { return $user; As you can see, the auth_user() function is a really basic function that simply checks the username and password of the user. The ping.php file then continues to send the new user list, like so: Again using a separate function, called send_userlist(), found in includes/user-functions.php, which looks like this: // Remove any inactive users (no ping for 15 seconds) // Get userlist // Queue command return true; The most important part in this function is the second last line, on which the json_queue_add() function is used. This is a special function that is used to queue different JSON commands, with different arguments, and when the json_queue_send() function is called, all the JSON commands are sent at once. This allows us to send multiple instructions back to the client at once. These functions look like this: // Add to commands array function json_queue_send { $data = array('queue' => $funcs); return_raw_json($data); Getting back to the ping.php file, after sending the new user list, it sends any new messages, using the send_messages() function: $lastactive = $user['lastactive']; // Get all new messages since last active if ($messages == false) { return false; } // Queue command It then updates the last active timestamp of the user, and finally sends all the commands with the json_queue_send() function. Now that the ping.php file has sent all the commands, it's back to the JS file, as it needs to handle the response. The handle_ping() function, which is used as the callback for the request (see the ping() function), begins with the basic stuff: Logger.info("Ping Received: " + data); // Transform JSON if (data == false) { if (typeof(data.error) != 'undefined') { if (typeof(data.queue) == 'undefined') { As you can see in the above example, it makes sure that a valid JSON response has been sent, and that an actual command queue was sent. After that the function needs to handle all the different commands. Seeing as we only have three commands yet, it's rather simple: // Determine function We loop through the queue, and use a switch statement to check which command we're dealing with. In each case, we do something different, for example when we're dealing with the 'update_lastactive' command, the lastactive variable is set to the updated value. In the above example you will see that a function called 'add_messages' is used to add any new messages. This function looks like this: messages.each( function(message) { var new_span = document.createElement('span'); div.appendChild(document.createElement('br')); div.scrollTop = div.scrollHeight; It basically loops through all the new messages, and then adds them (by inserting new HTML elements in the chat div). But before adding them, a check is made to make sure duplicate messages aren't added. Because of the way Ajax and the internet works, it's very easy to receive the same new messages multiple times, which means they'll show up multiple times. To prevent this from happening, each message has a unique token, and this is used to make sure that duplicate messages aren't added twice. This is basically how everything in the chat room is constantly updated, by sending a ping request every second, and then receiving new data back. Let's have a look at the final part of the chat room: sending messages.
To send a new message, a function called 'send_message()' is used, and this function sends the message to the chat server, using an Ajax request, like so: if (msg == '') { // Send message var ajax = new Ajax.Request(url, {method: 'post', parameters: pars, onComplete: handle_ping}); Logger.info("Sent message: " + pars); // Clear field The function first gets the value of the message field, and makes sure it isn't empty. After that it sends the message, and the user's credentials, to the chat.php file, using an Ajax request. The chat.php file only does two things: checks the user credentials and adds the new message. Checking the user credentials is extremely easy, as we've already got a function for that: auth_user() (see the previous section). If the user credentials are okay, the chat.php file then uses the add_message() function to add a message, and this function looks like this: // Get vars if (empty($message)) { return false; } // Insert message // All done It's pretty much a basic database insert, and there's nothing spectacular about it. Note how we generate a random token, to prevent the duplicate message problem, which I talked about in the previous section. I've taken you pretty much through everything in the Ajax/PHP chat, and I've shown you the most important parts. It's very understandable if you had a hard time following this article, as "the glue" between all the parts is still pretty much missing. That's why you can click here to download the complete Ajax/PHP chat. Make sure to open includes/global.php and change your MySQL details, so that they are correct. Also make sure you've already created the database, and setup the right structure. If you want to give the chat a test run, click here to view a live demo right here on PHPit.net. source: learnphp In the next part of this article series, we'll add some more features and improve our chat by making it more stable. Some of the new things we'll be adding are registered users, administrators, and a silenced chat room. |
|||||
| Copyrights Reserved AjaxProjects.com 2006-2013, Powered by Enozom - Mobile Development Company -Privacy Policy |