Coly010 Posted August 14, 2013 Posted August 14, 2013 Ok, so I have a little php/html file with a couple of divs where i want content to be loaded. the code: echo "<div class='chat'> <table width='100%'><tr> <td width='90%' class='td_name'><center><b>" . $fdname . "</b></center></td><td width='10%'><img src='img/ex.png' class='hide_div' onClick='hideChat()' onMouseOver='HoverExOver()' onMouseOut='HoverExOut()' /></td> </tr></table> <div id='chat_messages' style='overflow-y:scroll;'> </div> <div id='chat_input'> <input type='hidden' id='fr_id' value='" . $fr_id . "' /> <input type='hidden' id='chat_id' value='" . $c_id . "' /> <table width='100%'> <tr> <td width='100%'> <textarea id='imessage' cols='45'></textarea> </td> </tr> </table> </div> </div>"; then i have a JQuery function which will simply load some content into the #chat_messages div the function is: function load_messages(friend, chat) { $("#chat_messages").load("load_messages.php?friend=" + friend + "&ch_id=" + chat); } simple. now i have a $.post function for when the enter key is pressed in the textbox ( credit goes to Dayo for helping me here) $(document).ready(function() { $('#imessage').autogrow(); $("#imessage").bind("keypress", function (event) { $.post("update_imessages.php", { friend: $("#fr_id").val(), ch_id: $("#chat_id").val() }, function(data, status) { }); if (event.keyCode == 13) { event.preventDefault(); var friendid = $("#fr_id").val(); var chatid = $("#chat_id").val(); var msg = $(this).val(); post(msg, $(this), friendid, chatid); } }); }); function post(msg, selector, friendid, chatid) { selector.val(""); $.post("send_imessage.php", { i_message: msg, friend_id: friendid, ch_id: chatid }, function(data, status) { }); load_messages(friendid, chatid); } now i call the load_messages function again to reload the messages, and therefore auto-update the #chat_messages div with the new message. When the page firsts loads the load_messages() function takes about 1-2 secs to load the messages, but after the enter button is pressed in the textbox the load_messages() function takes around 24 secs before loading the messages, with the new message. Can anybody help me understand this, and possibly speed it up? Its supposed to be instant messaging, 24 secs isn't very instant. Thanks Quote
Dave Posted August 14, 2013 Posted August 14, 2013 I imagine this has something to do with your load_messages.php file as I cannot identify anything obvious from the jQuery you've posted. Post up your load_messages.php Quote
Coly010 Posted August 14, 2013 Author Posted August 14, 2013 here is my load_messages.php file: <?php include "mini_globals.php"; $fr_id = ""; $c_id = ""; if(isset($_GET['friend'])) { $fr_id = $_GET['friend']; } else { echo "FR_ID NOT SET<br />"; } if(isset($_GET['ch_id'])) { $c_id = $_GET['ch_id']; } else { echo "C_ID NOT SET<br />"; } $limit = 20; $select_msgs = $db->query("SELECT * FROM i_messages WHERE c_id = '$c_id' ORDER BY im_id DESC LIMIT 20"); $imessage_array = array(); while( $imessages = mysqli_fetch_assoc($select_msgs) ) { $imessage_array[] = $imessages; } $imessages = array_reverse($imessage_array); echo "<table width='100%' class='msg_table'>"; foreach($imessages as $im_ar) { if( $im_ar['s_id'] == $userid ) { echo "<tr class='user_sent_msg'> <td width='5%'>"; if( $im_ar['received'] == 1 ) { if( $im_ar['read'] == 1 ) { echo "<img src='img/read_icon.png' />"; } else { echo "<img src='img/received_icon.png' />"; } } else { if( $im_ar['sent'] == 1 ) { echo "<img src='img/sent_icon.png' />"; } } echo "</td>"; $time = substr($im_ar['time'], 10, 6); echo "<td width='85%'>" . $im_ar['message'] . "</td><td width='10%' class='time'>" . $time . "</td>"; } else if( $im_ar['s_id'] == $fr_id ) { $time = substr($im_ar['time'], 10, 6); echo "<tr class='friend_sent_msg'><td width='5%'></td><td width='85%'>" . $im_ar['message'] . "</td><td width='10%' class='time'>" . $time . "</td>"; $im_id = $im_ar['im_id']; $db->query("UPDATE i_messages SET received = 1 WHERE im_id = '$im_id'"); } echo "</tr>"; } echo "</table>"; ?> Quote
rockwood Posted August 15, 2013 Posted August 15, 2013 (edited) from where are you using JQuery lib ??(means using by online or on your server) Edited August 15, 2013 by rockwood Quote
Coly010 Posted August 15, 2013 Author Posted August 15, 2013 I am using the googleapi link. if its faster to download it and place it on my server I will do that. I ran another couple of tests to check how long after the enter key is pressed till the message appears on screen and I'm getting on average 47 seconds. If there is even an alternative to the way I'm doing this I'll look into it Quote
HauntedDawg Posted August 15, 2013 Posted August 15, 2013 Leave the jquery lib on googles server, it's alot faster than your's will ever be, it's also in cloud, so that an added bonus. You say that once you press the enter key it takes 47 seconds? That is your php script that's taking so long. If jquery was not loaded by the time you press the enter key, nothing will happen. But since you say it is actually triggering, by the time you have pressed enter, jquery has already loaded. Thus sending the request to your php script, and it is awaiting a response from your php to show the message. Quote
lucky3809 Posted August 15, 2013 Posted August 15, 2013 It could also be your internet connection, do a speed test. Or have someone else pull up your website and see if they also have the delay. I think your problem is either internet connection or server speed. Quote
Coly010 Posted August 15, 2013 Author Posted August 15, 2013 Is there a way to speed up the php script then? Like I've said when it first loads it takes around 1-2 seconds to load it, it loads quick enough. But then it takes so long the next time. And the more times the enter key is pressed the longer it takes the next time. Would it be faster if I combined the two files together, the send_imessage.php file and the load_messages file, and use the data parameter of the callback function in the $.post(); function? Also, I'm currently testing it using xammp or xampp however its spelt. So I'm just going to the localhost. Does that affect the speed? Quote
HauntedDawg Posted August 15, 2013 Posted August 15, 2013 Ok, Re-looking at your script. It's doing too much than what is needed. When pressing enter, your submitting the message. Once it has been succesfully sent, you then retrieve the messages, adding another call to the server. What you should do, is when submitting your message, use that same request to send back the message data to the chat bypassing the second call to the server. Quote
Coly010 Posted August 15, 2013 Author Posted August 15, 2013 Sounds good, so I'll change the send_imessage file to load the messages and then use $("#chat_messages").html(data); to load them. When I get back to my laptop I'll try this out and see if it improves the speed, thanks for the help everyone. Quote
Coly010 Posted August 15, 2013 Author Posted August 15, 2013 Right so it is definitely faster, but there is still a delay, and the longer the message the greater the delay, and as always the first message to be sent seems to be faster than the second message, no matter what. Is there any way that i can improve the php script of to load the messages? Quote
HauntedDawg Posted August 15, 2013 Posted August 15, 2013 If you have firebug installed, make sure that it's not double posting, then triple, then quadruple. I have noticed when using "bind" jquery function, that if done incorrectly, what can happen is: Press enter once, sends php once. Press enter again, sends php twice. Press again, sends php 3 times. If that is not the case, the only way further is to actually have a live demo of it. Quote
Coly010 Posted August 15, 2013 Author Posted August 15, 2013 yeah i noticed that myself, so i put into the php script a few if statements to avoid inserting it into the databae, but if it is double/triple posting, then it will still take a long time to finally load the messages. Is there an alternative to the "bind" function that i should look at? Quote
HauntedDawg Posted August 15, 2013 Posted August 15, 2013 (edited) Firstly, you could ".unbind()" every other function before doing yours as such: $("#imessage").unbind().bind Or, just use the .keypress(function(event) as such: $("#imessage").keypress(function(event) { Another alternative would be to have a javascript variable, such as "submittedOnce", when clicking enter, set this to true. When your script is finished loading, set it to false. Make sure when clicking enter, that it performs a check to make sure it is false before going ahead. Something along these lines: msgsSubmittedOnce = false; $(document).ready(function() { //Do other code here $("#imessage").bind('keypress', function(event) { if(!msgsSubmittedOnce) { msgsSubmittedOnce = true; // Do your script execution here // in your success function, you would have: // msgsSubmittedOnce = false; } }); // other code here }); It all depends how you implement it, the process flow you follow. And on closer inspection to your script: When i press enter, it firsts updates the messages, then submits my message, then updates again. Completely Redundant. You should always play the script out in your head, as such: When hitting enter, submit the message, show the updated messages. Then you convert that to code. Not sure why you followed the route you have got. There are many things that are making it slow. Edited August 15, 2013 by HauntedDawg Quote
Coly010 Posted August 15, 2013 Author Posted August 15, 2013 The update_imessages is simply setting some columns in the database to 1. however i do see how the $.post might slow this down. Ok i've changed it now, and used simply the .keypress() and it works so much faster now! i've rearranged some code, deleted some and what not and now it is far faster no matter how much is written, so that's definitely helpful. i also have it so that it will scroll to the bottom of the div when it loads and when a new message is sent. One question i do have now though is, if i have two users talking to each other, and one presses enter and it sends the message, how do i update the other user's div after the message has been sent? therefore i will avoid having to let the div reload every couple of seconds? Quote
HauntedDawg Posted August 15, 2013 Posted August 15, 2013 Unfortunately, we can not push data to the users browser, we could if you were using node.js, but at this point, it's not "stable" and requires quite a bit of work to install it onto your server. The only best method i suggest, is a 5second interval? And make sure if they go inactive, that it makes the interval longer, as you don't want unnecessary requests to the server. Quote
rockwood Posted August 15, 2013 Posted August 15, 2013 in html bad quotes also make some difference (due to quotes reading matter ) Quote
Coly010 Posted August 15, 2013 Author Posted August 15, 2013 well then for now an interval seems like the most sensible solution, even though i think that if there were 1000 users talking to each other to have a part of a page reload every 5 seconds 1000 times would become a bit tedious on the server. And then that again leads me to my next question, is there a way for me to check that if a person presses the x button on their webbrowser, so that i can update a column in the database to 0 to show they are offline, i know that there is a way to timeout sessions, but i'll need to look at that. Quote
HauntedDawg Posted August 16, 2013 Posted August 16, 2013 (edited) Yes, we have the jquery ".unload()" function for this. $(window).unload(function() { alert('Handler for .unload() called.'); }); Google Analytics use the same concept for tracking of users, when closing a tab, it sends a request to Google Analytics to kill your session and that's where they get the "Time on site" from. PS: Just read up that sometimes jquery unload does not get called, so let's rather use onbeforeunload: window.onbeforeunload = function() { alert('Bye Bye'); }; You can google "javascript trigger event when closing browser" Edited August 16, 2013 by HauntedDawg Quote
Coly010 Posted August 16, 2013 Author Posted August 16, 2013 Thanks HauntedDawg and rockwood for all the help, I appreciate it a lot. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.