Help - Search - Members - Calendar
Full Version: AJAX/PHP Instant Messaging System
Pixel2Life Forum > Help Section > PHP, ASP, MySQL, JavaScript and other Web/Database Programming Help
JoeyMagz
Ok, this is just an idea for a website messaging system, not a private messaging system. I wanted to make live messages to individual users or even multiple users sort of like an internet messaging system right on a webpage. It would follow the same principles as a private messaging system with database set-up, etc. The only difference is that there would be an ajax script checking for new messages every second or couple of seconds. The problem is, this may use a lot of system resources on the server. The cool thing about this would be that you would be able to make an instant messaging system for people browsing your website using php/ajax. I'm not sure if there is one already, but it seems like a pretty good idea.

Database set-up:

Members Table:
id - int primary key auto_increment.
username - varchar 15.
password - varchar 32. will be a md5 and sha1 hash of the password then the username.
e-mail - varchar 35.
admin - tinyint. will either be a value of 1 (admin) or the default, 0 (regular member)
last_ip - varchar 15. will store the last ip address person logged in with.

Buddy List:
uid - User ID from members table. int.
buddy - Buddies username or id. either varchar 15 or int.
blocked - Blocked users username or id. either varchar 15 or int.

Messages:
id - message id. int primary key auto_increment.
from - users name. varchar 15 characters.
to - buddies name. varchar 15 characters.
message - blob
time - timestamp CURRENT_TIMESTAMP.

The smartest way to work this is have a cron job or windows task set up to remove all messages 10 minutes or older from the database to save space. After you have the database set-up its simply a matter of having ajax set-up to run a php script to check for new messages every second.

Also, you would be able to make this look any way you wanted it to and you can pretty much make it do anything you wanted it to, right down to playing a sound when you receive a message. People would possibly even be able to play their own sounds when they received a message.

config.php
CODE
<?php
$_dbUsr = "username"; // database username.
$_dbPass = "password"; // database password.
$_db = "database"; // database you're using.
$_dbHost = "localhost"; // most likely using localhost.        

$_conn = @mysql_connect($_dbHost, $_dbUsr, $_dbPass);    
if(!$_conn) { // This executes the connect code and checks it for errors.        
    print "Error: Problem connecting to database server. Please check your config files.";    
}    
$_select = @mysql_select_db($_db, $_conn);    
if(!$_select) { // Executes the select database code and checks it for errors.        
    print "Error: Problem selecting database. Please check that database exists and is linked properly in config files.";
}    
?>


register.php
CODE
<?php
require("config.php");

$_user = mysql_real_escape_string($_POST['user']);
$_pass = md5(sha1($_POST['pass'].$_POST['user']));
$_email = mysql_real_escape_string($_POST['email']);

$memtab = "name of your members table";
$_ip = $_SERVER['REMOTE_ADDR'];

if ((!$_user) || (!$_pass) || (!$_email)) {
    print "You must fill in all fields before clicking the register button. Please go back and try again.";
} else {
    $sel = @mysql_query("SELECT * FROM $memtab WHERE username = '$_user'");
    if($sel) {
        print "A user with that username exists. Please go back and choose a new username.";
    } else {
        $ins = @mysql_query("INSERT INTO $memtab (username, password, email, last_ip) VALUES(\"$_user\", \"$_pass\", \"$_email\", \"$_ip\")");

        if ($ins) {
            print "Registration complete. You may now begin using 'title of instant messenger'.";
        } else {
            print "Error: Could not create user. Please go back and try again.";
        }
    }
}
?>


login.php
CODE
<?php    
require("config.php");        
$memtab = "name of your members table";    
$_user = mysql_real_escape_string($_GET['user']);    
$_pass = md5(sha1($_GET['pass'].$_GET['user']));        
$_sel = @mysql_query("SELECT * FROM $memtab WHERE username=$_user AND password=$_pass");  
while($r = @mysql_fetch_array($_sel)) {    
    $_SESSION['user'] = $r["username"]; // There is going to be a session_start() function on top of index.php which will be the main page.
    $admin = $r["admin"];
}
if($admin) { // If the admin column has a value of 1
    print "<script language='text/javascript' src='ajax.js'>buddyLoad($_SESSION['user'],1);</script>";
} else {
    print "<script language='text/javascript' src='ajax.js'>buddyLoad($_SESSION['user'],0);</script>";
}
?>


sendim.php
CODE
<?php
if(!$_GET['m'] || !$_GET['from'] || !$_GET['to']) {
    print "No message was sent.";
} else {
    $user = mysql_real_escape_string($_GET['from']);
    $buddy = mysql_real_escape_string($_GET['to']);
    $msg = mysql_real_escape_string($_GET['m']);

    $ins = @mysql_query("INSERT INTO messages ('from', 'to', 'message') VALUES(\"$user\", \"$buddy\", \"$msg\")"); /* The reason for only inserting the from, to, and message fields is because the message id should be set to auto_increment and the time should default to CURRENT_TIMESTAMP. */
    
    if(!$ins) {
        print "Message could not be sent. The server may be down.";
    }
}
?>


checkims.php
CODE
<?php
require("config.php");
require("style.php"); // This will be the script that styles the way an instant message looks.

$user = mysql_real_escape_string($_GET['user']);
$buddy = mysql_real_escape_string($_GET['buddy']);
$time = $_GET['time'];

$sel = @mysql_query("SELECT * FROM messages WHERE to='$user' AND from='$buddy' ORDER BY time DESC LIMIT 1");
while($r = @mysql_fetch_array($sel)) {
    $id = $r["id"];
    $message = $r["message"];
    $dbtime = $r["time"];
}

if ($time == $dbtime) {
    return
} else {
    style($user,$buddy,$dbtime,$message); // Style the instant message and display it.
}

?>


ajax.js
CODE
/* This should be the same for all AJAX scripts. You find out if the person's browser supports AJAX and set the AJAX object to a variable. */    
var xmlhttp;    
try {    
     xmlhttp=new XMLHttpRequest();    
} catch (e) {    
     try {    
         xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");    
     } catch (e) {    
         try {    
             xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");    
         } catch (e) {    
             alert("Your browser does not support AJAX!");    
             return false;    
         }    
    }    
}      
  
/* Since we're going to be using the GET method, we're going to check to see how long the url is with the message included. Since the max allowed length of a url is 2083 characters, we're going to make sure our url length is less than 2083 characters before we send the message to the intended buddy. */    
function checkIM() {
    var msg=document.getElementById('msg').value;
    var f=document.getElementById('user').value;
    var t=document.getElementById('buddy').value;
    var url='sendim.php?from='+f+'&to='+t+'&m='+msg;    
    if(url.length > 2083) {    
        document.getElementById('ims').innerHTML='Message too long.';    
    } else {    
        sendIM(url);    
    }    
}        

// After we've made sure the url is the right length, we can send it to our buddy.    
function sendIM(url) {    
     xmlhttp.onreadystatechange=function() {    
         if(xmlhttp.readyState==4) {    
             document.getElementById('ims').innerHTML+=xmlhttp.responseText;    
         }    
     }    
     xmlhttp.open("GET",url,true);    
     xmlhttp.send(null);    
}        

function cTime(time) {  
document.getElementById('time').value = time;
}

// This function is what we will be calling during the login process.    
function doLogin() {    
    var user=document.getElementById('username').value;    
    var pass=document.getElementById('pass').value;    
    var url='login.php?user='+user+'&pass='+pass;    
    xmlhttp.onreadystatechange=function() {    
        if(xmlhttp.readyState!=4) { // If the request is still loading, show loading image.                
            document.getElementById('main').innerHTML='<p><img src=images/loading.gif></p>';    
        } else {    
            document.getElementById('main').innerHTML=xhmlhttp.responseText;  
        }  
    }    
    xmlhttp.open("GET",url,true);    
    xmlhttp.send(null);    
}        

// The function we will be calling to show the users their buddylists.    
function buddyLoad(usr,admin) {    
    var url='buddylist.php?user='+usr+'&power='+admin;    
    xmlhttp.onreadystatechange=function() {    
        if(xmlhttp.readyState!=4) {    
            document.getElementById('main').innerHTML='<p><img src=images/loading.gif></p>';    
        } else {    
            document.getElementById('main').innerHTML=xmlhttp.responseText;            
        }    
    }        
    xmlhttp.open("GET",url,true);    
    xmlhttp.send(null);    
}        

// This will be what updates the users instant message window.    
function checkIMs() {    
    var usr=document.getElementById('user').value; // Hidden field with the persons username.        
    var f=document.getElementById('buddy').value; // Hidden field with the buddy's username.
var time=document.getElementById('time').value;
    var url='checkims.php?user='+usr+'&buddy='+f+'&time='+time;    
    xmlhttp.onreadystatechange=function() {    
        if(xmlhttp.readyState==4) {    
            document.getElementById('ims').innerHTML+=xmlhttp.responseText;
        }    
    }    
    xmlhttp.open("GET",url,true);    
    xmlhttp.send(null);    
}        

/* This is the instant message window timer that will run every second then call itself again to check for new im's. You can change the timer to run how ever often you would like it to, but keep in mind that if you have 20 users online, each with 5 im windows open, thats already 100 different timers running all calling the same php script from the checkIMs() function. This is where this idea may have problems. */    
function Timer() {    
    setInterval("checkIMs()", 1000);    
}


More stuff to come... Be sure to add your own input.

WHAT'S NEW
v.0.5.3 - Javascript update. Corrected some errors in the ajax.js file.
v.0.5.2 - PHP update. Completed checkims.php.
v.0.5.1 - Security and PHP update. Changed all htmlspecialchars and stripslashes to just mysql_real_escape_string. Cleaned up a lot of the code in the php files.
v.0.5 - PHP update. Added register.php.
v.0.4.1 - Security, PHP, and Database update. Added last_ip column to members table. Updated the SQL statement used in checkims.php. Now there is a htmlspecialchars() function added to all variables which call upon $_GET strings.
v.0.4 - PHP update. Added checkims.php.
v.0.3.1 - Database and Security update. Added time column to messages table. Changed password to md5 and sha1 hash of password + username.
v.0.3 - PHP update. Added config.php, login.php, and sendim.php files.
v.0.2.1 - Javascript update. Added checkIMs() and Timer() functions to ajax.js file.
v.0.2 - Javascript update. Created ajax.js file.
v.0.1 - Project started. Databases created.
rc69
My suggestion: if you're going to post this in the tutorials section, you should comment your code well enough that people can understand where you're going with it bigwink.gif

Otherwise, i can move this to the PHP/ASP help section and we can turn it into a huge debate about how to best go about making one of these victory.gif
JoeyMagz
yea i think that would be best...because this is a work in progress right now...i was planning on commenting as i went along.. =D I'll add some comments to the javascript stuff now though, but i still think moving it to the help section would be best.
rc69
Moved smile.gif
Spide®™
This sounds great, I don't know the first thing about scripting / codeing
But i had a brain wave ( or maybe not ), when reading your post

Say if i Designed a website, and it had members,
Could you have this setup like,

If i was doing live help ( Tutorials section on my website ) so i can help ppl around Photoshop
But have the code Email my members when i was doing live help, to tell them i'am online, and the messanger is open

Allso have a admin login, so the admin can open and close the messanger ?

Maybe Webcam ?

Probely a silly idea
but you never know lol

Allso can the GFX be made to how anybody wants it to look like ?
023-jimmy
Sounds interresting. I will be following your progress through this topic smile.gif.

I have been working with a combination of ajax and php too lately, but still discovering how to really get the most out of it. Reading through your code gives me a better understanding of how to use the code.

EDIT

I see you call the function your creating in the function. Don't know how to describe, but I mean this piece of code:

CODE
function Timer() {
    setInterval("checkIMs()", 1000);
    Timer();
}


The function your creating is Timer(); and inside that you call the function Timer();. This doesn't look logical?
JoeyMagz
Oops. Yea you're right jimmy thank you =D I'm still actually learning javascript as I program this! happy.gif I just read up on setTimeout and setInterval. It seems my code would have been correct if I used setTimeout, but since setInterval calls functions repeatedly I don't need to call the Timer() function again. Thanks again!

To answer Designe:
E-Mail members - I'll add some functions for that in the php files. Thanks for the idea. happy.gif

Admin Open/Close Messenger - Another good idea, and pretty easy to do, will definitely add that to php functions.

Graphics - Since this will be using a webpage window as the actual messenger, the owner/designer will be able to customize every aspect of the way it looks. biggrin.gif

Edit

Web Cam - After reading more into the webcam API, I need to create an ActiveX dll that will capture the footage from the webcam and then send that footage to the receiving users webpage. I don't think it will be too hard to do, but that's going to have to wait until after this first version is completed happy.gif lol That's going to require some real coding in vb.net or may even require c++. I'll start looking into that when I get home, as I'm at the base right now (I'm in the coast guard.) and I don't want to start browsing all kinds of websites because my internet is monitored. biggrin.gif

Another Edit

Designe - I just checked out your deviant page. Dude, I can't even believe someone is that crazy with graphics. I think I'll go out on a limb here and just say that you're graphics skills are amazing. blink.gif
023-jimmy
Have you already started at an online example? Or you just have the javascript code?
Arsenal19
This sounds like a great project.

If you need any help with the javascript or Ajax stuff let me know , i can prolly help.

Arsenal19
JoeyMagz
No, I haven't started anything yet. Basically, whenever I get time I come onto pixel2life forums and post some more functions and stuff.. lol I'm hoping that when I finish all of the features, someone will actually put it on their website for everyone to see with their own design and maybe some of their own scripting features. It'll be nice to see this baby grow, in a sense.

Thanks Arsenal happy.gif
023-jimmy
Well, when you're finished with it. I could put it on my website, for a testing periode. See how it will handle when lots of people use it. But before that happens I need to finish off my website, which will be a community for lovers of the harder styles music. But still have lots of work to do.
dotbart
Hey!
I like the ambition, I made the exact same as you about a year ago (well, maybe technology, database,... might differ but it's still a PHP/AJAX chatting script)

It features multiple conversations and uses XML to transfer the messages.

you can find the working script here
If you want, PM me and I can send you the code. If you need any advice, PM me aswell! :-)

Oh and by the way, don't expect it to be safe/bug-free/secure.... it's a test project smile.gif



B
JoeyMagz
yours is more of a chatroom type set up. I'm making more of a instant messaging system set up. Where you have a screen name and when people IM you, it opens a new window on your screen and shows the IM. Yours is still cool though =D
Spide®™
Thanks Joey, hope you get all your plans done
It would be great to see this

Oh yeah i have another question lol
About the skinning side of things, will you have to code in the gfx like CSS ? or will thay be a simple skin editor
like drag and drop, or simler, with not much coding to do, for ppl like me, who don't understand code lol
JoeyMagz
It's going to be CSS for the graphics.
023-jimmy
Just noticed something else. You've created the function Timer();. But you need to call the function too.

So:
CODE
function Timer() {    
    setInterval("checkIMs()", 1000);    
}


Will be:
CODE
function Timer() {    
    setInterval("checkIMs()", 1000);    
}
Timer();
JoeyMagz
That's going to be in the actual instant message window jimmy. I don't want the script to be calling for instant message updates on the buddy list window, that's going to be another function which actually checks for new instant messages and opens up another window. BTW, I'm going to be updating this some more soon, it's just that I'm in the coast guard and I'm trying to get all my paperwork and practicals done so I can leave for "A" school. I'll be updating more once I'm on the wait list, which should be by september 4th or 5th. Then all of my concentration will be on getting this thing done and polished.
JoeyMagz
Just added the register.php page to this. I have some more code to add when I get home on Friday. Also, in case you were wondering, I'm going to be adding some ajax code that checks for missing fields or duplicate username and e-mails in the javascript file, the stuff in register.php is just a double check to see if the javascript missed anything. At home right now I have a completed checkims.php as well as another couple scripts.
UnrealMedia
Very nice. I wish you would comment it though. We could learn something from it then. I hate being a copy and paste whore tongue.gif
023-jimmy
Really curious about your progress in this. Are you still busy with this? If so, show us some updates victory.gif!
JoeyMagz
I'm trying to update as often as possible... usually when ever I have a free minute or two I write a script for it. I have some more updates ready to post when I get home on sunday. At home I have a working script that I've been testing with my brother as well. There are a few bugs here and there but I'll update the post Sunday with a lot of those scripts.
Colin Lundy
heya i am very interested in your script, i would like to know if you have a index.php file for this? i am not sure wot way you are setting everything into motion

if you do could you please post it for me smile.gif many thanks
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.