Author: Ashraf Gheith
Updated on: 2017-01-08
Posted on: 1 year ago
Package: AJAX driven simple chat
Read this article to learn how you can implement an AJAX based chat room in your own site using this class that could well be used for instance as the basis of a live customer support system.
Contents
The Database Structure
The Frontend
The Backend
Conclusion
The Database Structure
Every chat room needs to keep the content of the chat lines stored somewhere. Some solutions use sessions, others use text files, but the most robust solutions use a database. So next time when you chat with some one, keep in mind it is saved somewhere there. :-)
For a simple chat room system we will need just one table, it stores the nickname of the user, what he said and the time when he said it. It is also useful to have something to distinguish what each user said. My proposal is to have a color field so we can show each user chat lines in a different way.
CREATE TABLE `chat` ( `id` INT(9) NOT NULL AUTO_INCREMENT , `usrname` VARCHAR(255) NOT NULL , `color` VARCHAR(6) NOT NULL , `chattext` TEXT NOT NULL , `chattime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (`id`) ) ENGINE = MyISAM CHARACTER SET utf8 COLLATE utf8_unicode_ci;
I have named the table "chat" for obvious reasons. It contains an ID field which is the primary key and so it is auto-incremented, a nickname, color and chattext fields, strings with different lengths. The chattime field is a timestamp field for which MySQL will set as default value to the current time. This is how we know when the chat line have been submitted. The table uses the MyISAM engine and character set is UTF-8 as it supports most languages.
The Frontend
Every good chat system has some kind of user management system. In our case we have just a user name. It is not complete solution but it is enough for the purposes of this tutorial.
When a user comes to the chat room page he needs to have a user name, so first we need to give him a way to choose one. Later we need to store this user name, so we do not need to ask him to enter his name every time he sends a message. That is why we will use sessions.
Here we create two sections in the frontend file: one for login and the other for chat. When the user comes for the first time, he will not have a user name in the session, and he will get a form to write down his user name and choose a color. When he submits the login form, the browser will be redirected to the chat screen. It is the same URL but the user sees one section a time.
Login section
Login section consists of two parts. The form on which the user provides his user name and color. Then he submits the form which will be handled by a script to set the session. After the browser returns to the first page again but now showing the chat interface instead of the login form. Let us create the first section with a script file named index.php:
<?php session_start(); if(IsSet($_SESSION[ "usrname" ]) && $_SESSION[ "usrname" ] == "") { ?> <html> <head> <title>Chat Room Example</title> <link rel="stylesheet" href="css/main.css" /> </head> <body> <h1>Please choose a nickname and a color</h1> <form action="login.php" method="post"> <table cellpadding="5" cellspacing="0" border="0"> <tr> <td align="left" valign="top">Nickname :</td> <td align="left" valign="top"> <input type="text" name="usrname" /> </td> </tr> <tr> <td align="left" valign="top">Color :</td> <td align="left" valign="top"> <select name="color"> <option value="000000">Black</option> <option value="000080">Navy</option> <option value="800080">Purple</option> <option value="00FFFF">Aqua</option> <option value="FFFF00">Yellow</option> <option value="008080">Teal</option> <option value="A52A2A">Brown</option> <option value="FFA500">Orange</option> <option value="CCCCCC">Gray</option> <option value="0000FF">Blue</option> <option value="00FF00">Green</option> <option value="FF00FF">Magenta</option> <option value="FF0000">Red</option> </select> </td> </tr> <tr> <td align="left" valign="top"></td> <td align="left" valign="top"><input type="submit" value="Login" /></td> </tr> </table> </form> </body> </html> <?php }else{ } ?>
First thing we do in this script is to call start_session(). We need to start the session before we print anything on the screen. After that a simple test, if the user has not registered his user name in the session we will show the form. If he did go through the login form, we show what is after the "else" keyword. Now it is empty but later we will add code there.
So if $_SESSION["usrname"] variable is empty, we show a form. Very simple, one table in a form with two fields: nickname and color. The user enters a user name and chooses a color from the dropdown select element. Then clicks on submit button that will submit the form to the login.php script.
Now let us create a simplified version of the login.php script. We are not fully validating the submitted values here for simplification reasons, but for security sake it is wise to assure the submitted values are valid.
<?php session_start(); $_SESSION['usrname'] = strip_tags($_POST['usrname']); $_SESSION['color'] = strip_tags($_POST['color']); header("Location: index.php"); ?>
Again, the first thing we do is to start our session with session_start(). We will do that many times. Do some basic filtering of the user name and color provided via the form, and assign the values to session variables. Then we redirect the user back to index.php page using the header() function. This time we have a session set with the user name value, so the if statement will activate the second part of the script this time.
Chat section
The second interface of this application is the chat window itself. We need to copy this code to the last part of the index.php for else section between the curly brackets.
?> <html> <head> <title>Chat Room Example</title> <script src="js/jquery.min.js"></script> <script src="js/main.js"></script> <link rel="stylesheet" href="css/main.css" /> </head> <body> <div id="view_ajax"></div> <div id="ajaxForm"> <input type="text" id="chatInput" /><input type="button" value="Send" id="btnSend" /> </div> </body> </html> <?
We will use AJAX to retrieve the new chat line entries from the database and to submit new chat lines. No user likes to have the page to refresh every couple of seconds to update the chat text. Older chat systems used a frame or flash. Using AJAX we can update the chat lines faster without reloading the page. I will use jQuery as it has built-in AJAX functions and I like its syntax.
First include jquery script in the header, then main.js script where we will put our JavaScript code, and finally our CSS file. I made two DIV sections, one to hold the chat window, and the other to hold the text box for the user to write what he wants to say. Remember the ID "view_ajax", we will need to use it in our JavaScript later.
body{ margin: 0; padding: 0; } #view_ajax { display: block; overflow: auto; width: 500px; height: 300px; border: 1px solid #333; margin: 0 auto; margin-top: 20px; } #ajaxForm{ display: block; margin: 0 auto; width: 500px; height: 50px; margin-top: 10px; } #chatInput{ width: 454px; }
The JavaScript Section
An important file for the chat system is main.js. This is where our AJAX requests are being processed. We have three functions and one event listener. Copy this code in main.js file:
var lastTimeID = 0; $(document).ready(function() { $('#btnSend').click( function() { sendChatText(); $('#chatInput').val(""); }); startChat(); }); function startChat(){ setInterval( function() { getChatText(); }, 2000); } function getChatText() { $.ajax({ type: "GET", url: "/refresh.php?lastTimeID=" + lastTimeID }).done( function( data ) { var jsonData = JSON.parse(data); var jsonLength = jsonData.results.length; var html = ""; for (var i = 0; i < jsonLength; i++) { var result = jsonData.results[i]; html += '<div style="color:#' + result.color + '">(' + result.chattime + ') <b>' + result.usrname +'</b>: ' + result.chattext + '</div>'; lastTimeID = result.id; } $('#view_ajax').append(html); }); } function sendChatText(){ var chatInput = $('#chatInput').val(); if(chatInput != ""){ $.ajax({ type: "GET", url: "/submit.php?chattext=" + encodeURIComponent( chatInput ) }); } }
This chat application will retrieve the chat status every two seconds, but we do not want to retrieve all the past chat lines every time. We already retrieved the newest ones, so we need a way to track which lines were retrieved for the last time.
As you may remember when we created the database table we added a primary key field named ID that is auto-incremented. We use that field value to track which line we have seen last. That is why we us a variable name lastTimeID in our JavaScript.
When the page is fully loaded, we register a click event listener to our button "btnSend". Whenever it is clicked we call the function sendChatText() function which is explained below. Also when the page is loaded we need to initiate the application. We will use startChat() function for that.
startChat() function will be called just once in our code at the start. It will use setInterval to evaluate a function call every two seconds as it was mentioned above. We need our chat window to be refreshed every two seconds to see what other users wrote. We use the getChatText() to retrieve the new chat lines.
getChatText() function will be called every two seconds. It sends an AJAX request with the last ID to a helper script named refresh.php. It gets as response JSON encoded data with the new chat lines.
Nowadays we use JSON to receive an array of data. In the past we used comma-separated values to return arrays back, but it was harder to encode and decode. Now we get an object that we can process easily.
By looping through the received JSON data we got the values of user name, color, chat time and chat text. That information is used to properly display in our chat window.
We also get the ID of every line, so we can keep track of which line was the last. With these details we create HTML code which shows a chat line to be appended in our chat window. Chat lines are displayed inside the DIV named "view_ajax", as you may remember it was mentioned above.
This function will read back chat lines and show them in our chat window. Now we need a function to let the user participate in the chat. For that we use sendChatText() function I mentioned before. We use it to send the text the user writes in the text box.
Every time the user clicks on send button, this function is called to send the new chat text using an AJAX rquest to script submit.php. That script will save the new chat text in the database, to be retrieved as a new line for the current user and also the other users in the same chat room.
Backend Section
The backend are the server side PHP helper scripts that call the class. The helper scripts handle the AJAX requests and call the class. We have two helper scripts, as mentioned before. We have refresh.php to refresh our chat window, and submit.php to submit new chat lines.
The helpers
The first helper script is refresh.php. It receives the last chat line ID from AJAX and pass it to a static class method that returns a JSON encoded response. Then the script outputs that as response to the AJAX requests. The code below is refresh.php code:
<?php require_once( "config.php" ); require_once( "/path/to/class/chatClass.php" ); $id = intval( $_GET[ 'lastTimeID' ] ); $jsonData = chatClass::getRestChatLines( $id ); print $jsonData; ?>
Second helper script is submit.php. It receives the chat text from AJAX and passes to static class method along with the user name and color from the session. We use start_session again to be able to access session data. The new data is inserted in the database. Below follows submit.php code:
<?php session_start(); require_once( "config.php" ); require_once( "/path/to/class/chatClass.php" ); $chattext = htmlspecialchars( $_GET['chattext'] ); chatClass::setChatLines( $chattext, $_SESSION['usrname'], $_SESSION['color']); ?>
Another file we need to create is config.php. it is a simple configuration file we are including in these two files where we define the database access variables.
<?php define("mysqlServer","localhost"); define("mysqlDB","mysqlDB"); define("mysqlUser","mysqlUser"); define("mysqlPass","mysqlPass"); ?>
The main class
The last file left to explain is the class itself. Let us copy this code in chatClass.php file:
<?php class chatClass { public static function getRestChatLines($id) { $arr = array(); $jsonData = '{"results":['; $db_connection = new mysqli( mysqlServer, mysqlUser, mysqlPass, mysqlDB); $db_connection->query( "SET NAMES 'UTF8'" ); $statement = $db_connection->prepare( "SELECT id, usrname, color, chattext, chattime FROM chat WHERE id > ? and chattime >= DATE_SUB(NOW(), INTERVAL 1 HOUR)"); $statement->bind_param( 'i', $id); $statement->execute(); $statement->bind_result( $id, $usrname, $color, $chattext, $chattime); $line = new stdClass; while ($statement->fetch()) { $line->id = $id; $line->usrname = $usrname; $line->color = $color; $line->chattext = $chattext; $line->chattime = date('H:i:s', strtotime($chattime)); $arr[] = json_encode($line); } $statement->close(); $db_connection->close(); $jsonData .= implode(",", $arr); $jsonData .= ']}'; return $jsonData; } public static function setChatLines( $chattext, $usrname, $color) { $db_connection = new mysqli( mysqlServer, mysqlUser, mysqlPass, mysqlDB); $db_connection->query( "SET NAMES 'UTF8'" ); $statement = $db_connection->prepare( "INSERT INTO chat( usrname, color, chattext) VALUES(?, ?, ?)"); $statement->bind_param( 'sss', $usrname, $color, $chattext); $statement->execute(); $statement->close(); $db_connection->close(); } } ?>
To connect to the database we need login information, so use constant values defined separately with MySQL connection values like the server name, database name, MySQL username and password.
In this class we have only two methods: one to retrieve chat lines from the database named getRestChatLines(). The other is to insert new chat lines to the database named as setChatLines().
The getRestChatLines() method receives one data element, the last chat line ID. It connects to MySQL database through the improved extension MySQLi and queries the database for the newest chat lines.
The queried chat lines must all be newer than our last chat line, and must not be older than one hour. We are limiting it to one hour to avoid causing excessive load to the server. The results are sorted in an array, and returned back as a JSON encoded data. Notice that the timestamp is converted to a readable time format.
The setChatLines() method receives three data elements: the chat text, who sent the text and its color. It connects to the MySQL database and inserts the new chat line with an INSERT statement. This method will not return anything.
As a final note, I just would like to remind that database access operations may fail eventually due to unexpected errors. The code shown above does not contain all the error checks that it should tp be robust. Error checking was omitted to avoid making the code look more complicated just for this tutorial.
Keep that in mind when implementing any kind of database access applications, so your code can be as robust as code written by a good professional developer.
Conclusion
Chat applications are not used for social sites exclusively anymore. Nowadays you can see simple chat systems on every kind of site, but often it is not called chat, they call it customer support instead.
With this tutorial you could learn how to create a simple chat room. Furthermore you could add a rooms database table and let the user choose a room, so you can have multiple chat rooms for different groups of users. You could also create private chat rooms in the same way, with just a few small modifications. This is just the tip of iceberg of what you can do with this class.
If you liked this article or you have questions or suggestions, just comment below. The class package is available right here for you to download. If you have great suggestions to improve the package I may implement your ideas in the class in the future. Just let me know.
You need to be a registered user or login to post a comment
Login Immediately with your account on:
Comments:
13. sd - Patrik Hudak (2016-10-07 00:57)
sd... - 0 replies
Read the whole comment and replies
12. help with location of files - Recovering Addicts (2016-07-10 13:09)
please help... - 2 replies
Read the whole comment and replies
12. help with location of files - Recovering Addicts (2016-07-10 13:09)
please help... - 2 replies
Read the whole comment and replies
11. Don't work - Kim graa (2016-06-11 15:39)
Chat...... - 2 replies
Read the whole comment and replies
10. ded - john (2016-04-18 10:33)
de... - 1 reply
Read the whole comment and replies
9. hi - ishwor kshetri (2016-02-25 07:30)
test... - 0 replies
Read the whole comment and replies
8. this code contain error - dinesh (2016-02-10 18:05)
error... - 0 replies
Read the whole comment and replies
7. jkgkj - Ravi (2015-12-22 09:37)
hjh... - 0 replies
Read the whole comment and replies
6. This report errors - zdenek (2015-12-11 12:36)
This report errors... - 0 replies
Read the whole comment and replies
5. hi there - Superluk (2015-12-03 21:52)
no sum... - 0 replies
Read the whole comment and replies