For my latest project, I was determined to avoid confusing Ajax requests by implementing my own JSON-RPC. Again, Zend Framework has made this incredibly easy.

The documentation recommends not running your Ajax request through the MVC. At first I was a little concerned, but it makes sense as the MVC does add a lot of unnecessary overhead.

I found this blog very helpful in figuring out how to do this.
The first step is to create a new bootstrap file.
I created one in public/api/1.0/jsonrpc.php

Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath('../../../library'),
    get_include_path(),
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);

$application->getBootstrap()
            ->bootstrap('doctrine')
            ->bootstrap('config');

// Instantiate server, etc.
$server = new Zend_Json_Server();
$server->setClass('App_Model_JsonRpc');

if ('GET' == $_SERVER['REQUEST_METHOD']) {
    // Indicate the URL endpoint, and the JSON-RPC version used:
    $server->setTarget('/api/1.0/jsonrpc.php')
           ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2);

    // Grab the SMD
    $smd = $server->getServiceMap();

    // Return the SMD to the client
    header('Content-Type: application/json');
    echo $smd;
    return;
}

$server->handle();

You may want to modify the $application->getBootstrap() line and add/remove bootstrap methods depending on your requirements. I need access to my database within my JSON-RPC server and use Doctrine as my ORM so I bootstrap that.

The most important line is:

$server->setClass('App_Model_JsonRpc');

This tells the server what class should handle all the JSON requests.

I also added a RedirectRule in my .htaccess file to hide the php extension. It’s unnecessary but the .php extension isn’t seen anywhere else on my site so I don’t want it on my JSON RPC server either.
I added this line…

RewriteRule ^api/([0-9].[0-9])/jsonrpc$ /api/$1/jsonrpc.php [NC,L]

…between these two lines:

RewriteRule ^.*$ - [NC,L]
RewriteRule ^api/([0-9].[0-9])/jsonrpc$ /api/$1/jsonrpc.php [NC,L]
RewriteRule ^.*$ index.php [NC,L]

[ad name=”Google Adsense 468×60″]
I then created a class called App_Model_JsonRpc and put it in my models directory.
/application/models/JsonRpc.php

class App_Model_JsonRpc
{

    /**
     * Return sum of two variables
     *
     * @param  int $x
     * @param  int $y
     * @return array
     */
    public function add($x, $y)
    {
        return  $x + $y;
    }
}

The doc blocks are very important as Zend_Json_Server generates the SMD based on the contents of the Doc block.

That’s it for the server. Send it the proper JSON code and it will add 2 numbers together and return the result.

Heres a quick example of how to use your new server.
I recommend installing the ZendJsonRpc jQuery plugin as it makes talking to your server much easier. You can download the plugin here.

<script src="/js/json2.js" type="text/javascript"></script>
<script src="/js/jquery.zend.jsonrpc.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
 myApi = jQuery.Zend.jsonrpc({url: '/api/1.0/jsonrpc'});

 alert('5+5=' + myApi.add(5,5));

 });
</script>

That’s it!
[ad name=”Google Adsense 468×60″]

Share

UPDATE: There was an error in one of the steps, the file /etc/ppp/options does not have to be edited, but /etc/ppp/pptpd-options does. The steps are now correct.

Like many Canadians I am jealous of the American’s and their ability to watch Hulu or listen to free music with Pandora. Both services claim they are working on making their site available to the world but I don’t like waiting.

[ad name=”Google Adsense 468×60″]

The way these types of sites figure out that you are not an American is by your IP address. I don’t know of any way of using an American IP address on my computer at home but it just so happens I have several Cloud Servers that are located in the US which of course have American IP addresses.

I have heard of people outside the US using the Proxy server or VPN server method but I had no idea it was so easy to setup. If you already have a cloud server up and running you could literally have it working in about 5 minutes. Setting it up from scratch should take about 10 minutes.

Below are the steps I followed to setup a Ubuntu based VPN server that allows me to access these coveted American sites from either my Mac or PC.

Cloud Computing & Cloud Hosting by Rackspace

I use Rackspace Cloud Servers for all my cloud server accounts but any VPS or dedicated server provider (provided they’re servers are located in the US) will work. I used Ubuntu 10.04 but any version of Ubuntu should work.

Connect to your server via SSH and start typing commands

If you just created a new Rackspace Cloud Server you’ll want to change your password.

passwd

Next update the package list and upgrade any packages that need updating.

apt-get update
apt-get upgrade

Now install the PPTP server package.

apt-get install pptpd

Specify the local and remote IP addresses. Default should work unless your local network is 192.168.123.0

nano /etc/pptpd.conf

Add these lines (or uncomment and modify existing ones)

localip 192.168.123.1
remoteip 192.168.123.234-238,192.168.123.245

Create a user account to connect to your server

nano /etc/ppp/chap-secrets

Add a user to the file in the following format:
username pptpd password *
For example:

john pptpd abc123 *

would create a user named john with a password abc123.
[ad name=”Google Adsense 468×60″]
Now restart the pptpd service

/etc/init.d/pptpd restart

You should be able to connect to your server via PPTP but you won’t be able to access any websites outside your server without a few more steps.

Setup DNS servers in the PPP Server options

nano /etc/ppp/pptpd-options

Uncomment and change the 2 lines starting with ms-dns
This sets up your server to make DNS requests via OpenDNS

ms-dns 208.67.222.222
ms-dns 208.67.220.220

Open the system configuration file and setup IP forwarding

nano /etc/sysctl.conf

Uncomment the following line

net.ipv4.ip_forward=1

To make the system configuration changes take effect:

sysctl -p

Edit this file

nano /etc/rc.local

Add these two lines above exit (0) in this file:

/sbin/iptables -t nat -A POSTROUTING -s 192.168.123.0/24 -o eth0 -j MASQUERADE
/sbin/iptables -I FORWARD -p tcp -syn -i ppp+ -j TCPMSS -set-mss 1356

Server is done. You can connect to this server using any PPTP client.

Cloud Computing & Cloud Hosting by Rackspace

Share

I just pre-ordered my 16GB iPad 3G along with my $0.20 Rogers Micro SIM card even though I hope to eventually use Fido. Rogers data plans are not outrageous. They certainly could be better. Interestingly the 250MB for $15 is technically a little cheaper than the US one because of the exchange rate. The $35/month for 5GB is a little steep. I have 6GB for my iPhone and only pay $30. The combined data package sounds interesting. Hopefully Fido offers the same. I rarely use anywhere near 500MB a month so it would be great to use the extra 5.5GB for my iPad. Since the iPad is unlocked and the data plans are pay as you go it might be interesting to try out Bell or Telus. I’ll try Rogers a least for a month when I get my iPad and see what the data plans are for the other carriers. At the very least I’ll switch to Fido to take advantage of the data plan sharing feature.

Rogers blog iPad details: http://bit.ly/cKT5VY
[ad name=”Google Adsense 468×60″]

Share