Trying to use pusher.com to update my highchart spline instead of database polling

I have a highchart spline that updates every second to show the incoming call rate per second. So naturally its polling my db each second and returning the amount of calls that have come in during the past second. Not that great. Bit of lag, missing calls, not too great.

function in highchart currently looks like this:
function requestData() { 
$.ajax({ 
    url: 'assets/db/incoming_callrate.php', 
    success: function(point) { 
        var series = chart.series[0], 
            shift = series.data.length > 20; // shift if the series is longer than 20

        // add the point 
        chart.series[0].addPoint(point, true, shift); 

        // call it again after one second 
        setTimeout(requestData, 1000); 
    }, 
    cache: false 
}); 

Open in new window

in my page that the chart resides I am currently using pusher to update what caller number I'm on and to increment a progress bar and trigger a datatable (read: works awesome)

Part of that is below:
channel.bind('newcall', function(data) { 
    if (data['currentcaller']){ 
     document.getElementById("incoming_callers").innerHTML = data['currentcaller']; 
     document.getElementById("bar9").setAttribute('title', data['currentpercent']); 
     var percent = $('#bar9').attr('title'); 
$('#bar9').animate({width: percent},1000);

Open in new window

So in my case if I could somehow trigger my chart each second with the total amount of calls that have occurred in the past second that would be great. Random thoughts were:

I was guessing I need to establish a new variable something like: var callrate = 0;

Then each time pusher sends a notice of a call, increment the call rate up: ++callrate;

and magically somehow: once a second goes by, trigger a function for the chart to update with the total amount of calls that have occurred in the past second and reset the callrate variable to zero for the next second.

Any idea on above?

My database request returns the x and y axis: x being the time() *1000 and y being the amount of callers in one second.
LVL 1
tjyoungAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
clockwatcherConnect With a Mentor Commented:
Here's a php version:
<?php

include './pusher-php-server-master/lib/Pusher.php';

$app_id = 'APP_ID';
$app_key = '675505d46e4e94515943';
$app_secret = 'APP_SECRET_KEY';

$pusher = new Pusher($app_key, $app_secret, $app_id);

while (1) {

        $time_stamp = time() * 1000;
        $calls_per_sec = rand(1,100); // replace with your db query
        $pusher->trigger('my-ee-app', 'chart-event', array($time_stamp, $calls_per_sec));
        sleep(1);
}

?>

Open in new window


The pusher php library is downloadable at https://github.com/pusher/pusher-php-server

You'd need to hook in your database code and would want to run that under php's command line interface (php-cli) on your server-- probably in a supervisord managed process so that it would restart if it goes down.
0
 
clockwatcherCommented:
Unless you need data about every single call and if you're going to be updating your chart every second rather than live anyway, it seems like it would make more sense to continue with your call/sec rate.  Use a server process to push the call/sec data to pusher app
    while True:
        data = [time.time() * 1000, randint(0,100) ]  # replace with your db call
        print data
        p['my-ee-app'].trigger('chart-event', data)
        time.sleep(1)

Open in new window

and instead of having your clients poll for it, have them subscribe to that event.  Then you really don't have to change much of anything-- just replace your ajax call with a pusher event.  It should be a lot more efficient than having your client poll.
        channel.bind('chart-event', function(data) {
                var series = chart.series[0];
                shift = series.data.length > 20; // shift if the series is longer than 20
                chart.series[0].addPoint(data, true, shift);
        });

Open in new window



I posted a sample at  http://mostlywrong.info/ee.htm

Full client code
<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

		<script src="http://js.pusher.com/2.0/pusher.min.js"></script>

		<script type="text/javascript">
var pusher = new Pusher('675505d46e4e94515943');
var channel = pusher.subscribe('my-ee-app');

$(function () {

        var chart = new Highcharts.Chart({
            chart: {
                type: 'spline',
		renderTo: 'container'

            },
            title: {
                text: 'Incoming Calls'
            },
            subtitle: {
                text: 'EE Pusher Test'
            },
            xAxis: {
                type: 'datetime',
		tickPixelInterval: 150,
		maxZoom: 20 * 1000

            },
            yAxis: {
                title: {
                    text: 'Call rate'
                },
                min: 0,
		max: 100,
                minorGridLineWidth: 0,
                gridLineWidth: 0,
            },
            tooltip: {
                valueSuffix: ' calls/sec'
            },
            plotOptions: {
                spline: {
                    lineWidth: 4
                }
            },
            series: [{
                name: 'Call Center',
		data: []
                } ]
            ,
            navigation: {
                menuItemStyle: {
                    fontSize: '10px'
                }
            }
        });

        channel.bind('chart-event', function(data) {
                var series = chart.series[0];
                shift = series.data.length > 20; // shift if the series is longer than 20
                chart.series[0].addPoint(data, true, shift);
        });

    });
    

		</script>
	</head>
	<body>
<script src="./js/highcharts.js"></script>
<script src="./js/modules/exporting.js"></script>

<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>

	</body>
</html>

Open in new window


Full Server
import ConfigParser
import pusher
import time
from random import randint

def main():
    config = ConfigParser.ConfigParser()
    config.readfp(file('config.ini','r'))
    p = pusher.Pusher(app_id=config.get('pusher','app_id'),
                      key=config.get('pusher','key'),
                      secret=config.get('pusher','secret'))
    while True:
        data = [time.time() * 1000, randint(0,100) ] # replace with db query
        print data
        p['my-ee-app'].trigger('chart-event', data)
        time.sleep(1)

if __name__ == '__main__':
    main()

Open in new window

0
 
tjyoungAuthor Commented:
This appears to  be brilliant.. so brilliant I dont have a clue about the server part. Where does that go?
Excited at the solution, but dumbfounded at the server part...
0
 
tjyoungAuthor Commented:
if i understand you right your saying do the db query and send the result each second to pusher to send out.
that sound right?
wouldnt be able to show the server version as php by chance would you?
0
 
tjyoungAuthor Commented:
Love it
Many thanks!
0
All Courses

From novice to tech pro — start learning today.