High CPU usage due to Ajax Shoutbox

2019-08-05 23:33发布

Alright, so I have made a shoutbox, I have been using it for some time, but just recently it has come to my attention that it eats at the cpu usage because of so many calls to the script, and I am wondering how I can go about fixing its performance.

Here is the js script for the shoutbox.

var current_shouts = 0;
            function $shoutid(eleid) {
                return document.getElementById(eleid);
            }
            function urlencode(u) {
                u = u.toString();
                var matches = u.match(/[\x90-\xFF]/g);
                if (matches) {
                    for (var mid = 0; mid < matches.length; mid++) {
                        var char_code = matches[mid].charCodeAt(0);
                        u = u.replace(matches[mid], '%u00' + (char_code & 0xFF).toString(16).toUpperCase());
                    }
                }
                return escape(u).replace(/\+/g, "%2B");
            }
            function shouts() {
                clearTimeout(getshout);
                var xmlHttp = (window.XMLHttpRequest) ? new XMLHttpRequest : new ActiveXObject("Microsoft.XMLHTTP");
                xmlHttp.open("GET", "shoutbox/shouts.php?i=" + Math.random());
                xmlHttp.onreadystatechange = function() {
                    if (this.readyState == 4) {
                        if (parseInt(this.responseText) > current_shouts) {
                            getshouts();
                            current_shouts = parseInt(this.responseText);
                        }
                        getshout = setTimeout("shouts()", 1000);
                    }
                }
                xmlHttp.send(null);
            }
            function getshouts() {
                var xmlHttp = (window.XMLHttpRequest) ? new XMLHttpRequest : new ActiveXObject("Microsoft.XMLHTTP");
                xmlHttp.open("GET", "shoutbox/getshouts.php?i=" + Math.random());
                xmlHttp.onreadystatechange = function() {
                    if (this.readyState == 4) $shoutid("shoutbox").innerHTML = this.responseText;
$shoutid("shoutbox").scrollTop = $shoutid("shoutbox").scrollHeight;
                }
                xmlHttp.send(null);
            }
            function push_shout() {
                shout();
                return false;
            }
            function shout() {
                var xmlHttp = (window.XMLHttpRequest) ? new XMLHttpRequest : new ActiveXObject("Microsoft.XMLHTTP");
                xmlHttp.open("POST", "shoutbox/shout.php");
                var data = "user=" + urlencode($shoutid("user").value) + "&" + "shout=" + urlencode($shoutid("shout").value);
                xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                xmlHttp.setRequestHeader("Content-length", data.length);
                xmlHttp.onreadystatechange = function() {
                    if (this.readyState == 4) {
                        if (!this.responseText) $shoutid("shout").value = "";
                        else {
                            alert(this.responseText);
                        }
                        getshouts();
                    }
                }
                xmlHttp.send(data);
                return true;
            }
            var getshout = setTimeout("shouts()", 1000);

I'm not really the brightest crayon when it comes to js so I am not really sure how to go about fixing this. The call to shouts.php is what is really eating up at my cpu.

Here is the script for shouts.php

<?php
$db = new mysqli('localhost', 'username', 'pass', 'database');

if($db->connect_errno > 0){
   die('Unable to connect to database [' . $db->connect_error . ']');
}
    $stmt = $db->query("SELECT COUNT(id) FROM shout");
    while ($shout = $stmt->fetch_assoc()) {
    echo implode($shout);
    }
session_write_close();
?>

I read up on the session locking problem so I added in the session_write_close(); but this doesn't seem to help with my issue at all.

Any tips would be greatly appreciated!

2条回答
不美不萌又怎样
2楼-- · 2019-08-05 23:52

Here is some basic code that will cache the output so you're not doing as much processing.

$cachefile = 'mycache.txt';
$timeout = 5;

//if there is no cache, or the cache is older that the specified timeout
if( !file_exists($cachefile) || ( filemtime($cachefile) + $timeout < time() ) ) {
   //your existing code here!
   $shouttext = implode($shout);
   echo $shouttext;
   file_put_contents($cachefile, $shouttext);
} else {
   echo file_get_contents($cachefile);
}
查看更多
贪生不怕死
3楼-- · 2019-08-05 23:55

This is one of those things where tuning the code isn't necessarily going to help a whole bunch. You're essentially DDoS attacking your own hardware. My suggestion in the immediate future would be to bump up the javascript setTimeout frequency from 1000 to 2000 or higher. In the long run: upgrading hardware, moving to a faster/lighter storage solution (Redis is my personal favorite), both would be wise.

查看更多
登录 后发表回答