<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kristian Kristensen's Blog</title>
	<atom:link href="http://zianet.dk/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://zianet.dk/blog</link>
	<description></description>
	<lastBuildDate>Fri, 22 Jun 2012 00:40:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Running FreeSwitch on Windows Azure Virtual Machines</title>
		<link>http://zianet.dk/blog/2012/06/22/running-freeswitch-on-windows-azure-virtual-machines/</link>
		<comments>http://zianet.dk/blog/2012/06/22/running-freeswitch-on-windows-azure-virtual-machines/#comments</comments>
		<pubDate>Fri, 22 Jun 2012 00:39:22 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[FreeSwitch]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Misc]]></category>
		<category><![CDATA[VoIP]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=1103</guid>
		<description><![CDATA[After the announcement that Windows Azure will support hosting real Virtual Machine images I&#8217;ve wanted to test it out and see if I could run FreeSwitch on it. FreeSwitch is an open source soft switch for telephony, kind of like Asterisk. The short conclusion is that yes you can run it, but it&#8217;s severely limited [...]]]></description>
			<content:encoded><![CDATA[<p>After the announcement that <a href="https://www.windowsazure.com/en-us/home/features/virtual-machines/">Windows Azure will support hosting real Virtual Machine images</a> I&#8217;ve wanted to test it out and see if I could run FreeSwitch on it. FreeSwitch is an open source soft switch for telephony, kind of like Asterisk.<br />
<em>The short conclusion is that yes you can run it, but</em> it&#8217;s <a href="http://social.msdn.microsoft.com/Forums/en/WAVirtualMachinesforWindows/thread/4c093e33-eb86-4639-b325-c295fa8bfc5d">severely limited since Azure doesn&#8217;t allow more than 25 port pairs to be forwarded per VM</a>. Read ahead for what it took to get it up and running, plus some screenshots.</p>
<p>After you get access to the preview Azure portal, setting up the VM is pretty easy. There&#8217;s a gallery of OS images to choose from (4 in total) of which I chose Ubuntu 12.04 LTS. My VM was setup in &#8220;East US&#8221; and I chose an Extra-Small instance, since it was just for testing. During the setup you can choose to add a user account with a password or upload your SSH key. After the box boots up, you can log into it using the Virtual IP (VIP) that Azure assigns, or the DNS alias created during setup. So far so good. You ssh in, and it&#8217;s a virtual machine like any other.</p>
<p>The new Azure portal is pretty nifty and much better compared to it&#8217;s previous Silverlight incarnation. It&#8217;s all HTML and all the data is retrieved via a REST API that you can access yourself as well. That means that nothing is hidden, and you could build your own Azure Dashboard if you wanted to. The default one shows the state of the machine along with some pretty usage graphs.</p>
<p><a href="http://zianet.dk/pics/azure-vm/azure-vm-freeswitch-dashboard.png"><img src="http://zianet.dk/pics/azure-vm/azure-vm-freeswitch-dashboard-thumb.png" alt="Azure VM FreeSwitch Dashboard" /></a></p>
<p>Getting FreeSwitch to run on this new virtual machine requires the normal source check out dance. The following commands will do fine.<br />
Prerequisites for Ubuntu 12.04 LTS (from <a href="http://wiki.freeswitch.org/wiki/Installation_Guide#Ubuntu_12.04_LTS_64bit">the Wiki</a>):</p>
<pre class="brush: bash;">
sudo apt-get install git-core build-essential autoconf automake libtool libncurses5 libncurses5-dev gawk libjpeg-dev zlib1g-dev pkg-config libssl-dev
sudo update-alternatives --set awk /usr/bin/gawk
</pre>
<p>Then:</p>
<pre class="brush: bash;">
cd /usr/local/src
git clone git://git.freeswitch.org/freeswitch.git

cd /usr/local/src/freeswitch
./bootstrap.sh
./configure
make &amp;&amp; make install
make all cd-sounds-install cd-moh-install
</pre>
<p>After that you can start up FreeSwitch by going to the bin directory in /usr/local/freeswitch/bin and run &#8220;./freeswitch&#8221;. This will run the out of the box configuration which has users and a dialplan set up. It&#8217;s good enough for testing.</p>
<p>FreeSwitch will try and auto detect the NAT settings and it&#8217;s own IP. It will fail because the VM is locked down on a firewall level. Hence it&#8217;ll only find it&#8217;s own internal IP in the 10.*.*.* range. This of course won&#8217;t help us when we&#8217;re trying to register a user agent to it. Next step is therefore to setup some endpoint mappings.</p>
<p>We want UDP traffic on port 5060 to be forwarded to our VM, as well as some RTP ports. Looking through the documentation for the command line tools and looking at the portal, I had first thought that you couldn&#8217;t automatically forward port ranges. That sucks when you want to forward the entire RTP UDP space. I thought (naively?) that a simple hack would just be to loop through all the ports and forward them one by one. Alas that doesn&#8217;t work. There is a limitation to the amount of endpoints mappings one can create for an Azure VM. That limit is 25 port pairs. That throws a big wrench in the plan of hosting a soft switch on Azure VM&#8217;s. However, we can still get the proof of concept going by forwarding a couple of RTP ports and then limiting FreeSwitch to only use these.</p>
<p><a href="http://zianet.dk/pics/azure-vm/azure-vm-freeswitch-endpoints.png"><img src="http://zianet.dk/pics/azure-vm/azure-vm-freeswitch-endpoints-thumb.png" alt="Azure VM FreeSwitch Endpoint Mappings" /></a></p>
<p>We also need to tell FreeSwitch to only use this mapped port range. So open up conf/autoload_configs/switch.conf.xml and set rtp-start-port and rtp-end-port to the start and end of the mapped port range.<br />
Then we&#8217;ll update the external_rtp_ip and external_sip_ip to be the Virtual IP assigned by Azure. Open vars.xml and make the change. Last you want to update the internal sip profile to use the external sip and rtp ip&#8217;s instead of what FreeSwitch tries to guess by using auto nat, which is the default. So open up conf/sip_profiles/internal.xml and replace:</p>
<pre class="brush: xml;">
&lt;param name=&quot;ext-rtp-ip&quot; value=&quot;auto-nat&quot;/&gt;
&lt;param name=&quot;ext-sip-ip&quot; value=&quot;auto-nat&quot;/&gt;
</pre>
<p>with:</p>
<pre class="brush: xml;">
&lt;param name=&quot;ext-rtp-ip&quot; value=&quot;$${external_rtp_ip}&quot;/&gt;
&lt;param name=&quot;ext-sip-ip&quot; value=&quot;$${external_sip_ip}&quot;/&gt;
</pre>
<p>Then recycle FreeSwitch. You should now be able to register to your Virtual IP or DNS alias by Azure using one of the test accounts in the default config. Once your softphone registers try and call another extension on the box or call 9664 for some lovely Hold Music.</p>
<p>Most of the setup needed I found on the <a href="http://wiki.freeswitch.org/wiki/Amazon_ec2">FreeSwitch EC2 wiki page</a>.</p>
<p>This is the first preview release of Virtual Machines running on Windows Azure. I hope that being able to map port ranges and definitely having more than 25 endpoint mappings is something that&#8217;ll come soon to Azure. From <a href="http://social.msdn.microsoft.com/Forums/en/WAVirtualMachinesforWindows/thread/4c093e33-eb86-4639-b325-c295fa8bfc5d">the responses on the forum it seems like it&#8217;s on the roadmap</a>, although without any indication of time frame. Fingers crossed for sooner rather than later.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2012%2F06%2F22%2Frunning-freeswitch-on-windows-azure-virtual-machines%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2012/06/22/running-freeswitch-on-windows-azure-virtual-machines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Issues with MySQL and ODBC on Centos 5</title>
		<link>http://zianet.dk/blog/2012/04/05/issues-with-mysql-and-odbc-on-centos-5/</link>
		<comments>http://zianet.dk/blog/2012/04/05/issues-with-mysql-and-odbc-on-centos-5/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 20:27:14 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[FreeSwitch]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[ODBC]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=1096</guid>
		<description><![CDATA[I run a server with Centos 5.6. For a number of reasons I need to have a newer version of MySQL running on it than what Centos 5 comes with stock. So I used IUS to install MySQL 5.1. Great. It works, I have a somewhat recent version of MySQL. Problem was I&#8217;m running FreeSwitch [...]]]></description>
			<content:encoded><![CDATA[<p>I run a server with Centos 5.6. For a number of reasons I need to have a newer version of MySQL running on it than what Centos 5 comes with stock. So I used <a href="http://iuscommunity.org/">IUS</a> to install MySQL 5.1. Great. It works, I have a somewhat recent version of MySQL. Problem was I&#8217;m running FreeSwitch (FS) on this box as well. And I&#8217;ve linked up FS to MySQL via ODBC. For some reason that connection went wonkers at some point during an upgrade (I suspect). So the problem was that FS was in a limbo mode where it couldn&#8217;t start because MySQL ODBC didn&#8217;t work.</p>
<p>The error I got was something along the lines of:</p>
<p><em>isql: relocation error: /usr/lib64/libmyodbc3.so: symbol strmov, version libmysqlclient_15 not defined in file libmysqlclient.so.15 with link time reference</em></p>
<p>Starting FreeSwitch gave me the same error. </p>
<p>You can use isql to test that the connection is indeed there, so I had a good baseline test for figuring out when this would actually work again. Googling the error was of no help. Upgrading packages via Yum back and forth was no help either. The solution for me ended up being very simple. Install a new version of the MySQL ODBC Connector and update my ODBC DSN to use this new driver.</p>
<ol>
<li>Get the <a href="http://dev.mysql.com/downloads/connector/odbc/">newer ODBC package for your platform here</a>.</li>
<li>Install it using &#8220;rpm -i mysql-connector-odbc-5.1.10-1.rhel5.x86_64.rpm&#8221; &#8211; that was the version I used.<br />
The RPM will automatically add the new driver to /etc/odbcinst.ini, so you need to update your /etc/odbc.ini to use this new driver instead.</li>
</ol>
<p><em>/etc/odbcinst.ini</em></p>
<p>[MySQL]<br />
Description             = ODBC for MySQL<br />
Driver          = /usr/lib64/libmyodbc3.so<br />
Setup           = /usr/lib/libodbcmyS.so<br />
FileUsage               = 1<br />
UsageCount              = 2</p>
<p>[MySQL ODBC 5.1 Driver]<br />
Driver          = /usr/lib64/libmyodbc5.so<br />
UsageCount              = 1</p>
<p><em>/etc/odbc.ini</em></p>
<p>[MyDSN]<br />
Driver          = MySQL ODBC 5.1 Driver</p>
<p>My old DSN used &#8220;MySQL&#8221; as the driver but with the new package installed I had to change that to &#8220;MySQL ODBC 5.1 Driver&#8221;. That&#8217;s of course re-nameable.</p>
<p>After this running isql gave me a connection to the database and everything was back to normal. Posting it here in case someone has the same issue and can&#8217;t fidn a solution.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2012%2F04%2F05%2Fissues-with-mysql-and-odbc-on-centos-5%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2012/04/05/issues-with-mysql-and-odbc-on-centos-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sencha Touch Cookbook Published</title>
		<link>http://zianet.dk/blog/2012/02/18/sencha-touch-cookbook-published/</link>
		<comments>http://zianet.dk/blog/2012/02/18/sencha-touch-cookbook-published/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 21:42:48 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Book]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Misc]]></category>
		<category><![CDATA[Sencha Touch]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=1089</guid>
		<description><![CDATA[During the fall of 2011 I was a technical reviewer of the now published book on Sencha Touch by Packt Publishing. The books goes through a number of different scenarios for building apps with Sencha Touch. Reviewing a book has been an interesting experience. The process is fairly simple. You receive a number of chapters [...]]]></description>
			<content:encoded><![CDATA[<p>During the fall of 2011 I was a technical reviewer of the now published book on Sencha Touch by Packt Publishing. The books goes through a number of different scenarios for building apps with Sencha Touch.</p>
<img title="Sencha Touch Cookbook" src="https://www.packtpub.com/sites/default/files/imagecache/productview/5443EXP_Sencha%20Touch%20Cookbook.jpg" alt="Sencha Touch Cookbook" width="125" height="151" />
<p>Reviewing a book has been an interesting experience. The process is fairly simple. You receive a number of chapters on a fixed schedule. You then have to comment on it, suggest improvements, fact check what&#8217;s written as well as make sure the code is reasonable. This then has to be sent back to the editor.<br />
The bonus of being a reviewer is that you get your name in the book. So if you go to the Amazon Look Inside feature and flip through the first few pages you&#8217;ll find a little blurb about me.</p>
<p>You can find and buy the book online at <a href="http://www.packtpub.com/sencha-touch-for-creating-cross-platform-html5-apps-cookbook/book">Packt Publishing</a> or on <a href="http://www.amazon.com/Sencha-Touch-Cookbook-Ajit-Kumar/dp/1849515441/ref=sr_1_1?ie=UTF8&amp;qid=1329600726&amp;sr=8-1">Amazon</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2012%2F02%2F18%2Fsencha-touch-cookbook-published%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2012/02/18/sencha-touch-cookbook-published/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running Erlang Webmachine on Heroku</title>
		<link>http://zianet.dk/blog/2011/12/16/running-erlang-webmachine-on-heroku/</link>
		<comments>http://zianet.dk/blog/2011/12/16/running-erlang-webmachine-on-heroku/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 16:45:43 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Cedar]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Erloku]]></category>
		<category><![CDATA[Github]]></category>
		<category><![CDATA[Heroku]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Mochiweb]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Webmachine]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=1069</guid>
		<description><![CDATA[When Heroku released their new stack Cedar they opened the door for a whole new set of components to run on their platform. To support running other components on Heroku you need a build pack that tells Heroku how to build and run your app. Heroku&#8217;s published a build pack for Erlang as well as [...]]]></description>
			<content:encoded><![CDATA[<p>When <a href="http://www.heroku.com">Heroku</a> released their <a href="http://devcenter.heroku.com/articles/cedar">new stack Cedar</a> they opened the door for a whole new set of components to run on their platform. To support running other components on Heroku you need a build pack that tells Heroku how to build and run your app. Heroku&#8217;s published a <a href="https://github.com/heroku/heroku-buildpack-erlang">build pack for Erlang</a> as well as <a href="https://github.com/JacobVorreuter/hello-erlang">a demo app</a>. This demo app uses straight up Mochiweb as a web server. </p>
<blockquote><p>MochiWeb is an Erlang library for building lightweight HTTP servers. </p>
<p><a href="https://github.com/mochi/mochiweb">Mochiweb Github Repo</a></p></blockquote>
<p>Webmachine runs on top of Mochiweb and is</p>
<blockquote><p>A REST-based system for building web applications.</p>
<p><a href="https://github.com/basho/webmachine">Webmachine Github Repo</a></p></blockquote>
<p>In this blog post I&#8217;ll show how to get a Webmachine app running on Heroku.</p>
<h3>Let&#8217;s get to it</h3>
<p>So here are the steps to get a vanilla <a href="http://webmachine.basho.com">Webmachine</a> app up and running on Heroku.</p>
<pre class="brush: bash;">
$ git clone git://github.com/basho/webmachine
$ cd webmachine
$ make
$ ./scripts/new_webmachine.sh my-erlang-app /tmp
$ cd /tmp/my-erlang-app
$ make
</pre>
<p>You can now run <em>&#8220;./start.sh&#8221;</em> and open your browser on <a href="http://localhost:8000">http://localhost:8000</a> and see your new awesome Hello World Webmachine app. Now we want to deploy it to Heroku.<br />
Make sure you have Ruby and the Heroku gem installed. If not run:</p>
<pre class="brush: bash;">
$ gem install heroku
</pre>
<p>Then setup our app:</p>
<pre class="brush: bash;">
$ git init
$ heroku create my-erlang-app -s cedar
$ heroku config:add BUILDPACK_URL=http://github.com/heroku/heroku-buildpack-erlang.git
</pre>
<p>This initializes a new Git repository in our app directory, creates the heroku app. The final line setups the build pack that cedar should use when deploying the app.</p>
<p>Let&#8217;s add the source files to the Git repo and start hammering out some code.</p>
<pre class="brush: bash;">
$ git add Makefile README rebar rebar.config start.sh src/* priv/dispatch.conf
</pre>
<p>Next we want to update our rebar.config:</p>
<pre class="brush: erlang;">
%%-*- mode: erlang -*-
{sub_dirs, [&quot;rel&quot;]}.
{deps_dir, [&quot;deps&quot;]}.
{erl_opts, [debug_info]}.

{deps, [{webmachine, &quot;1.9.*&quot;, {git, &quot;git://github.com/basho/webmachine&quot;, &quot;HEAD&quot;}}]}.
</pre>
<p>Create the Procfile which <a href="https://github.com/ddollar/foreman">Foreman</a> will use to control our app:</p>
<pre class="brush: plain;">
web: erl -pa ebin deps/*/ebin -noshell -boot start_sasl -s reloader -s my-erlang-app
</pre>
<p>You know have the major components in place for Heroku deployment. If you want to test it out run:</p>
<pre class="brush: bash;">
$ ./rebar get-deps compile
$ foreman start
</pre>
<p>Of course this requires that you&#8217;ve <a href="https://github.com/ddollar/foreman">Foreman</a> in your path. If not install Ruby and run &#8220;gem install foreman&#8221;. If all goes well your app will start up and you&#8217;ll be able to point your browser to <a href="http://localhost:8000">http://localhost:8000</a> and see the output.</p>
<p>Before we can push to Heroku we need to update the application start up code for the generated Webmachine app. When Cedar attempts to start your application it&#8217;ll define the port on which your app should listen/bind. Hence we need to read out this value and tell Webmachine to use it. Also we want to update the logging, basically turning it off (more about this later) and we want to just bind to the default catch all ip of 0.0.0.0.</p>
<p>Open up <em>my_erlang_app_sup.erl</em> in the <em>src/</em> directory.<br />
Change the init method so it looks like this:</p>
<pre class="brush: erlang;">
init([]) -&gt;
     {ok, Dispatch} = file:consult(filename:join(
                          [filename:dirname(code:which(?MODULE)),
                          &quot;..&quot;, &quot;priv&quot;, &quot;dispatch.conf&quot;])),

    Port = list_to_integer(os:getenv(&quot;PORT&quot;)),
    io:format(&quot;start web server on port ~p~n&quot;, [Port]),
    WebConfig = [
                 {ip, &quot;0.0.0.0&quot;},
                 {port, Port},
%                 {log_dir, &quot;priv/log&quot;},
                 {dispatch, Dispatch}],
    Web = {webmachine_mochiweb,
           {webmachine_mochiweb, start, [WebConfig]},
           permanent, 5000, worker, dynamic},
    Processes = [Web],
    {ok, { {one_for_one, 10, 10}, Processes} }.
</pre>
<p>This reads out the port number that Cedar has assigned to our app in line 6 and passes it to the Webmachine config. Also it binds to the right IP in line 9 and disables the log dir in line 11.</p>
<p>Make sure it compiles by running the <em>rebar</em> command again:</p>
<pre class="brush: bash;">
$ ./rebar get-deps compile
</pre>
<p>Before we push to Heroku you might want to change the output message of your app. Open <em>&#8220;src/my_erlang_app_ressource.erl&#8221;</em> and change the <em>&#8220;to_html&#8221;</em> function.</p>
<p>Now do the add and commit dance to git:</p>
<pre class="brush: bash;">
git add &lt;input-changed-file-list-here&gt;
git commit -m &quot;initial commit before push to Heroku&quot;
</pre>
<p>Next run</p>
<pre class="brush: bash;">
$ git push heroku master
</pre>
<p>Point your browser to <a href="http://my-erlang-app.heroku.com">http://my-erlang-app.heroku.com</a> and you should see your output message as defined in <em>&#8220;src/my_erlang_app_ressource.erl&#8221;</em>.</p>
<p>To see what&#8217;s going on when Cedar boots up your app run <em>&#8220;heroku logs&#8221;</em>. This will spit out the same output you see when you run foreman locally. This is a great (and the) way to debug why your app isn&#8217;t starting up.</p>
<p>I&#8217;ve pushed <a href="https://github.com/kristiankristensen/erloku">my repository to Gibhub</a> and deployed the app to Heroku. It&#8217;s called <strong>Erloku</strong> and you can <a href="http://erloku.herokuapp.com/">check it out here</a></p>
<h3>Next steps</h3>
<p>Here are a couple of things that I&#8217;d like to continue to work on.</p>
<ul>
<li>By default Webmachine comes with a logger that outputs to tiles. Since this doesn&#8217;t go well with Heroku which expects and redirects output from  Standard Output and Standard Error to its logs. Therefore it would be nice to implement a logger for Webmachine that outputs to StdOut and StdErr. <a href="http://lists.therestfulway.com/pipermail/webmachine_lists.therestfulway.com/2011-April/000501.html">Doing this shouldn&#8217;t be too hard</a>.</li>
<li>Get two dynos running an Erlang Node to talk with each other. Cedar probably has walls in place that won&#8217;t allow this, but if possible it would be mighty cool.</li>
</ul>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2011%2F12%2F16%2Frunning-erlang-webmachine-on-heroku%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2011/12/16/running-erlang-webmachine-on-heroku/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ErlChat &#8211; A Simple Chat Server Written In Chicago Boss, A Web Framework For Erlang</title>
		<link>http://zianet.dk/blog/2011/12/13/erlchat-a-simple-chat-server-written-in-chicago-boss-a-web-framework-for-erlang/</link>
		<comments>http://zianet.dk/blog/2011/12/13/erlchat-a-simple-chat-server-written-in-chicago-boss-a-web-framework-for-erlang/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 19:55:29 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Chatify]]></category>
		<category><![CDATA[ChicagoBoss]]></category>
		<category><![CDATA[ErlChat]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=1053</guid>
		<description><![CDATA[Recently I&#8217;ve been exploring Erlang and its web frameworks. As part of this exploration I found Chicago Boss. This blog post is a pointer into the simple chat server I built using Erlang and Chicago Boss. Jordan Orelli and Seth Murphy from Hacker School built Chatify as a demo application for Brubeck: Brubeck is a [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been exploring <a href="http://www.erlang.org">Erlang</a> and its web frameworks. As part of this exploration I found <a href="http://www.chicagoboss.org">Chicago Boss</a>. This blog post is a pointer into the simple chat server I built using <a href="http://www.erlang.org">Erlang</a> and <a href="http://www.chicagoboss.org">Chicago Boss</a>.</p>
<p>Jordan Orelli and Seth Murphy from Hacker School built <a href="http://github.com/jordanorelli/chatify">Chatify</a> as a demo application for <a href="http://www.brubeck.io">Brubeck</a>:</p>
<blockquote><p>Brubeck is a flexible Python web framework that aims to make the process of building scalable web services easy.</p></blockquote>
<p>Chatify is a simple chat application built with Brubeck as the backend and HTML and Javascript as the front end.<br />
I decided to reimplement the backend in <a href="http://www.chicagoboss.org">Chicago Boss</a> and reuse the front-end. The result is <a href="http://github.com/kristiankristensen/erlchat">Erlchat</a>.</p>
<p>Here&#8217;s the main page of <a href="http://github.com/kristiankristensen/erlchat">Erlchat</a>, where you enter your nickname before logging into the chat:</p>
<p><a href="http://github.com/kristiankristensen/erlchat/wiki/images/erlchat-1.png"><img src="http://github.com/kristiankristensen/erlchat/wiki/images/erlchat-1.png" alt="Click to View in Fullsize - ErlChat Main Page" style="width:400px"/></a></p>
<p><a href="http://en.wikipedia.org/wiki/Bert_and_Ernie">Bert and Ernie</a> chat&#8217;s away:</p>
<p><a href="http://github.com/kristiankristensen/erlchat/wiki/images/erlchat-2.png"><img src="http://github.com/kristiankristensen/erlchat/wiki/images/erlchat-2.png" alt="Click to View in Fullsize - ErlChat Chat Screen 1" style="width:400px"/></a></p>
<p>They&#8217;re loving it!</p>
<p><a href="http://github.com/kristiankristensen/erlchat/wiki/images/erlchat-3.png"><img src="http://github.com/kristiankristensen/erlchat/wiki/images/erlchat-3.png" alt="Click to View in Fullsize - ErlChat Chat Screen 2" style="width:400px"/></a></p>
<p>The code is really simple. Mostly because the required parts for building a chat server is built into Chicago Boss in the form of a message queue abstraction. However, the reason it works is because of Erlangs ability to scale out. Each call to retrieve messages is a long polling HTTP call, and hence blocks a connection. Since Erlang scales to many thousands of processes and Chicago Boss takes advantage of that, it really isn&#8217;t a problem.</p>
<p>The following function gets called by the client when he wishes to retrieve the messages that have occurred in <i>Channel</i> since his last retrieveal (<i>LastTimestamp</i>). It blocks on the call to <i>boss_mq:pull</i>.</p>
<pre class="brush: erlang;">
receive_chat('GET', [Channel, LastTimestamp]) -&gt;
    {ok, Timestamp, Messages} = boss_mq:pull(Channel, list_to_integer(LastTimestamp)),
    {json, [{timestamp, Timestamp}, {messages, Messages}]}.
</pre>
<p>Sending a message is a simple HTTP POST that creates a new message and pushes it on to the <i>Channel</i> message queue. It uses the utility method seen below.</p>
<pre class="brush: erlang;">
send_message('POST', [Channel]) -&gt;
    create_and_push_message(Channel, list_to_binary(Req:post_param(&quot;message&quot;)), Req:post_param(&quot;nickname&quot;)),
    {output, &quot;ok&quot;}.

create_and_push_message(Channel, Message, Username) -&gt;
    NewMessage = message:new(id, Message, Username, erlang:localtime()),
    boss_mq:push(Channel, NewMessage).
</pre>
<p>Check out the README as well as the source. <a href="http://github.com/kristiankristensen/erlchat">It&#8217;s all up on Github</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2011%2F12%2F13%2Ferlchat-a-simple-chat-server-written-in-chicago-boss-a-web-framework-for-erlang%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2011/12/13/erlchat-a-simple-chat-server-written-in-chicago-boss-a-web-framework-for-erlang/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Giving EM-Smsified Some Server Love</title>
		<link>http://zianet.dk/blog/2011/11/23/giving-em-smsified-some-server-love/</link>
		<comments>http://zianet.dk/blog/2011/11/23/giving-em-smsified-some-server-love/#comments</comments>
		<pubDate>Wed, 23 Nov 2011 16:55:00 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[EM-SMSified]]></category>
		<category><![CDATA[Gem]]></category>
		<category><![CDATA[SMSified]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=1045</guid>
		<description><![CDATA[I just pushed the next release of my EM-SMSified gem to Github and Rubygems. This release (0.3.0) adds an EventMachine HTTP server to make it easy to react to SMSified callbacks. Installing is easy as always: gem install em-smsified Using it is equally easy. Here&#8217;s an example of a &#8220;pong&#8221; server that sends a pong [...]]]></description>
			<content:encoded><![CDATA[<p>I just pushed the next release of my EM-SMSified gem to Github and Rubygems. This release (0.3.0) adds an EventMachine HTTP server to make it easy to react to <a href="http://www.smsified.com">SMSified</a> callbacks.</p>
<p>Installing is easy as always:</p>
<pre>gem install em-smsified</pre>
<p>Using it is equally easy. Here&#8217;s an example of a &#8220;pong&#8221; server that sends a pong back to any received text message:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'yaml'
require 'em-smsified'
require 'eventmachine'
require 'evma_httpserver'

smsified = EventMachine::Smsified::OneAPI.new('username', 'password')

EM.run do
  Signal.trap(&quot;INT&quot;) { EM.stop }
  Signal.trap(&quot;TRAP&quot;) { EM.stop }

    puts &quot;Hit CTRL-C to stop&quot;
    puts &quot;==================&quot;
    puts &quot;Server started at &quot; + Time.now.to_s

    puts &quot;Starting incoming SMSified callback server&quot;

    EM.start_server '0.0.0.0', 8080, EventMachine::Smsified::Server do |s|
    s.on_incoming_message do |msg|
      puts &quot;Message received &quot; + Time.now.to_s
      puts &quot;#{msg.sender_address} says '#{msg.message}' to #{msg.destination_address}&quot;
      smsified.send_sms( :message        =&gt; 'Pong',
                         :address        =&gt; msg.sender_address,
                         :sender_address =&gt; msg.destination_address) do |result|
        puts &quot;Pong sent &quot; + Time.now.to_s
      end
    end
  end
end
</pre>
<p>A more elaborate example is up on Github (<a href="https://github.com/kristiankristensen/em-smsified/blob/master/examples/pong_server.rb">examples/pong_server.rb</a>).</p>
<p>The server supports incoming messages on which you need to set a subscription (<a href="http://smsified.com/sms-api-documentation/receiving#inbound_subscriptions">SMSified &#8211; Receiving Messages</a>) and delivery notifications. The latter is set up when you send an sms message by adding the <em>:notify_url</em> parameter.</p>
<h3>Use cases</h3>
<p>Having a server that&#8217;s easy to use from EventMachine makes it easy to implement more advanced text message scenarios: </p>
<ul>
<li>You could couple this with the <a href="https://github.com/igrigorik/em-websocket">em-websocket</a> gem and add easy websocket callbacks from received text messages.</li>
</ul>
<p><a href="http://github.com/kristiankristensen/em-smsified/">Source on Github</a> as usual, and <a href="http://rubygems.org/gems/em-smsified">gem on Rubygems</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2011%2F11%2F23%2Fgiving-em-smsified-some-server-love%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2011/11/23/giving-em-smsified-some-server-love/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Putting EventMachine In the SMSified Gem</title>
		<link>http://zianet.dk/blog/2011/11/17/putting-eventmachine-in-the-smsified-gem/</link>
		<comments>http://zianet.dk/blog/2011/11/17/putting-eventmachine-in-the-smsified-gem/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 22:18:14 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tropo]]></category>
		<category><![CDATA[EM-SMSified]]></category>
		<category><![CDATA[EventMachine]]></category>
		<category><![CDATA[Gem]]></category>
		<category><![CDATA[SMSified]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=1030</guid>
		<description><![CDATA[I wanted to utilize EventMachine for something and real and since I&#8217;ve been tinkering with telephony stuff recently I thought something that sends text messages might be a good candidate. Instead of rewriting everything from scratch I started with the SMSified Ruby gem instead. SMSified is a service by Tropo that makes it really easy [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to utilize <a href="http://rubyeventmachine.com/">EventMachine</a> for something and real and since I&#8217;ve been tinkering with telephony stuff recently I thought something that sends text messages might be a good candidate. Instead of rewriting everything from scratch I started with the <a href="http://www.smsified.com">SMSified</a> Ruby gem instead. <a href="http://www.smsified.com">SMSified</a> is a service by <a href="http://www.tropo.com">Tropo</a> that makes it really easy to send text messages. Since the service is still in beta sending text messages is free. Pretty neat. SMSified has a Ruby gem that comes with a test suite. Hence I thought it would be a good starting point.</p>
<p>Installing the new gem is easy</p>
<pre class="brush: bash;">
gem install em-smsified
</pre>
<p>Here&#8217;s some example code showing how to send an SMS via SMSified:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'eventmachine'
require 'em-smsified'

oneapi = EventMachine::Smsified::OneAPI.new(:username =&gt; 'user', :password =&gt; 'password')

EM.run do
  oneapi.send_sms(:address =&gt; '14155551212', :message =&gt; 'Hi there!', :sender_address =&gt; '13035551212') do |result|
    puts result.inspect
  end
end
</pre>
<p>The <a href="http://github.com/smsified/smsified-ruby">original gem</a> uses HTTParty to do HTTP requests. To mock these in the spec suite the gem used <a href="https://github.com/chrisk/fakeweb">FakeWeb</a>. FakeWeb doesn&#8217;t work with EventMachine and therefore my first step was to replace FakeWeb with <a href="https://github.com/bblimke/webmock">WebMock</a>, which works with a number of Ruby HTTP frameworks. After that I DRY&#8217;ed up the code a bit to contain where HTTP requests were being made. Then I added EventMachine via the <a href="https://github.com/igrigorik/em-http-request">EM-HTTP-Request</a> gem. To EM&#8217;ify the new library I had to modify the original interface to take an anonymous block. This block gets called when the request to SMSified returns. This is where you can check what was returned and perform any updates. This is shown in the code sample above.</p>
<p>There are more examples in <a href="http://github.com/kristiankristensen/em-smsified">the source tree</a> and there&#8217;s also some <a href="http://kristiankristensen.github.com/em-smsified">YARD documentation</a>.</p>
<p><a href="http://twitter.com/#!/jsgoecke">Jason Goecke</a> and <a href="http://twitter.com/#!/thedyers">John Dyer</a> wrote the original SMSified gem making my job so much easier.</p>
<p><a href="https://rubygems.org/gems/em-smsified">em-smsified on RubyGems</a>.<br />
Source on <a href="https://github.com/kristiankristensen/em-smsified">Github</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2011%2F11%2F17%2Fputting-eventmachine-in-the-smsified-gem%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2011/11/17/putting-eventmachine-in-the-smsified-gem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TweetHose Released as a Gem</title>
		<link>http://zianet.dk/blog/2011/10/22/tweethose-released-as-a-gem/</link>
		<comments>http://zianet.dk/blog/2011/10/22/tweethose-released-as-a-gem/#comments</comments>
		<pubDate>Sat, 22 Oct 2011 19:45:15 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Gem]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[RubyGems]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=1025</guid>
		<description><![CDATA[I&#8217;ve just released a gem called TweetHose to RubyGems. Here&#8217;s the short description of what it is: TweetHose lets you easily generate a daemon that listens to the Twitter firehose. When keywords you&#8217;re interested in appears, you can set up a callback. Should make it easy to create that Justin Bieber tracking app you&#8217;ve always [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just released a gem called <a href="https://rubygems.org/gems/tweethose">TweetHose to RubyGems</a>. Here&#8217;s the short description of what it is:</p>
<blockquote><p>TweetHose lets you easily generate a daemon that listens to the Twitter firehose. When keywords you&#8217;re interested in appears, you can set up a callback. Should make it easy to create that Justin Bieber tracking app you&#8217;ve always wanted.</p></blockquote>
<p>Install it via a quick:</p>
<pre>gem install tweethose</pre>
<p>Source is up on <a href="https://github.com/kristiankristensen/tweethose">Github</a>.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2011%2F10%2F22%2Ftweethose-released-as-a-gem%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2011/10/22/tweethose-released-as-a-gem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Simple Way to Generate One File MSDN Style Documentation for Your .NET Projects</title>
		<link>http://zianet.dk/blog/2011/06/10/the-simple-way-to-generate-one-file-msdn-style-documentation-for-your-net-projects/</link>
		<comments>http://zianet.dk/blog/2011/06/10/the-simple-way-to-generate-one-file-msdn-style-documentation-for-your-net-projects/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 07:00:23 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[Ghostdoc]]></category>
		<category><![CDATA[MSDN]]></category>
		<category><![CDATA[Sandcastle]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=895</guid>
		<description><![CDATA[I was recently tasked with generating code documentation. The last time I had to do that I used NDoc and the XML Comments that the C# compiler (csc.exe) spits out. Turns out that NDoc is no longer, or at least it&#8217;s not being maintained. Instead the new kid on the block is Sandcastle. It might [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently tasked with generating code documentation. The last time I had to do that I used NDoc and the XML Comments that the C# compiler (csc.exe) spits out. Turns out that NDoc is no longer, or at least it&#8217;s not being maintained. Instead the new kid on the block is <a href="http://sandcastle.codeplex.com/">Sandcastle</a>.<br />
It might be my memory failing, but I seem to remember that setting up NDoc to generate MSDN style documentation was pretty easy. My initial foray into using Sandcastle was not. This post describes a super simple way to generate MSDN style documentation that&#8217;s contained in a single CHM file.</p>
<p>We&#8217;ll need some software. So go ahead and download and install the following:</p>
<ul>
<li>Sandcastle &#8211; <a href="http://sandcastle.codeplex.com/">http://sandcastle.codeplex.com</a></li>
<li>Sandcastle Help File Builder &#8211; <a href="http://shfb.codeplex.com">http://shfb.codeplex.com</a><br />
This includes a guide that installs and sets up the required software. It&#8217;s important to download and set up HTML Help Workshop v.1 as part of this process.</li>
</ul>
<p><em>Optional:</em></p>
<ul>
<li>GhostDoc &#8211; <a href="http://submain.com/products/ghostdoc.aspx">http://submain.com/products/ghostdoc.aspx</a><br />Not required, but it makes it super easy to generate XML documentation from within Visual Studio. It&#8217;ll even auto generate some of the text. The free version is fine, but obviously the paid version includes more features.</li>
</ul>
<p>With all of the software installed and in place, it&#8217;s time to generate some documentation.</p>
<ul>
<li>Open Sandcastle Help File Builder GUI and start a new project.</li>
<li>Right click Documentation Sources on the right and select &#8220;Add Documentation Source&#8221;.</li>
<li>Find and select your solution file (*.sln).</li>
<li>Select &#8220;HtmlHelp1&#8243; under HelpFileFormat under the &#8220;Build&#8221;-category.</li>
<li>Fill out whatever other properties you want. HelpTitle and HtmlHelpName are obviously good for putting in the name of your project. The &#8220;Show Missing Tags&#8221;-category is good for fine tuning what&#8217;s added if you haven&#8217;t explicityly documented everything.</li>
<li>Hit CTRL+SHIFT+B or select &#8220;Build Project&#8221; from the &#8220;Documentation&#8221;-menu.</li>
<li>Wait.</li>
<li>You should now have a .chm file in your output folder.</li>
</ul>
<p>Remember if your distribute the CHM file by putting it on the internet and allowing people to download that they need to Unblock the file first, before opening it. Otherwise all of the links inside will fail. You can see my post on <a href="http://zianet.dk/blog/2011/03/14/x-509-certificates-and-downloads-via-internet-explorer/">X.509 Certificates and Downloads Via Internet Explorer</a> for a description of the troubles that can occur when downloading files and they&#8217;re marked as being unsafe.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2011%2F06%2F10%2Fthe-simple-way-to-generate-one-file-msdn-style-documentation-for-your-net-projects%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2011/06/10/the-simple-way-to-generate-one-file-msdn-style-documentation-for-your-net-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSON Proxy Using IIS Reverse Proxy for Fun and Profit</title>
		<link>http://zianet.dk/blog/2011/06/07/json-proxy-using-iis-reverse-proxy-for-fun-and-profit/</link>
		<comments>http://zianet.dk/blog/2011/06/07/json-proxy-using-iis-reverse-proxy-for-fun-and-profit/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 14:55:28 +0000</pubDate>
		<dc:creator>Kristian Kristensen</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[Sencha Touch]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[ARR]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[JSON-P]]></category>
		<category><![CDATA[Proxy]]></category>
		<category><![CDATA[URL Rewrite]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://zianet.dk/blog/?p=954</guid>
		<description><![CDATA[Developing mobile applications using Sencha Touch that will be packaged up using PhoneGap to run as a &#8220;native&#8221; app on a phone can be a bit of a pain. Especially if you&#8217;re accessing some kind of API. Because of restrictions in the browser, you&#8217;re not allowed to do cross site requests, meaning it&#8217;s difficult to [...]]]></description>
			<content:encoded><![CDATA[<p>Developing mobile applications using Sencha Touch that will be packaged up using PhoneGap to run as a &#8220;native&#8221; app on a phone can be a bit of a pain. Especially if you&#8217;re accessing some kind of API. Because of restrictions in the browser, you&#8217;re not allowed to do cross site requests, meaning it&#8217;s difficult to call external API&#8217;s during development. You&#8217;re likely to run your new shiny mobile app from a file on your hard drive or served up by a locally running web server. But the API&#8217;s you need to access are probably running on a another external server. Hitting that API will give you a sad message from Chrome, because of the &#8220;Same Origin Policy&#8221;. Safari will just return nothing, and ignore you. IE9 and Firefox are not even options, because they don&#8217;t run WebKit. You can of course do all of your development in PhoneGap, deploying to an emulator or a real device and always test on that. But it adds quite a bit of time to the feedback loop and for prototyping it&#8217;s especially nice to have the fast feedback loop afforded by the browser, the console and the inspector. So how do we get around this annoyance. One way is to use <a href="http://en.wikipedia.org/wiki/JSONP">JSON-P</a> and the <a href="http://dev.sencha.com/deploy/touch/docs/output/Ext.data.ScriptTagProxy.html">ScriptTagProxy</a>. Another is to utilize a reverse proxy server, which is what I&#8217;ll describe in this post.</p>
<p>I&#8217;m developing on Windows 7, so this is a description on how to set it up using IIS. <a href="http://learn.iis.net/page.aspx/659/reverse-proxy-with-url-rewrite-v2-and-application-request-routing/">This guide on the IIS.net website</a> explains things in more detail. If you&#8217;re running on Mac or Linux you could setup nginx, Apache or another web server. Most web server software include proxy rewrite and reverse proxy capabilities.</p>
<p>Before we get started here&#8217;s a quick and simple diagram of what we&#8217;re trying to achieve:</p>
<pre>
Browser < => Local Web Server (IIS) Proxy To => External Server with API
</pre>
<p>First you&#8217;ll want to <a href="http://learn.iis.net/page.aspx/489/using-the-application-request-routing-module/">install the Application Request Routing module</a>. This module works with the URL Rewrite module to proxy requests back and forth between your web server and some other back end server. Next step is to enable the ARR module on your IIS Root.</p>
<p>Then on your web site that hosts your mobile application code (basically just a virtual directory to your web root of your Sencha Touch application) you want to configure the URL Rewrite module. There are a couple of options for doing this, one is through the IIS Management GUI, the other is by adding the appropriate configuration in your web.config file. I&#8217;ll list the configuration settings in the following, but you can just as well set this up using the GUI and <a href="http://learn.iis.net/page.aspx/659/reverse-proxy-with-url-rewrite-v2-and-application-request-routing/">the guide</a>. Another options is to copy in the following configuration settings, and then tinker with it using the GUI afterwards. The IIS Manager GUI is basically a nice way of manipulating web.config files.</p>
<p>If your virtual directory doesn&#8217;t have a web.config (it probably doesn&#8217;t since it&#8217;s serving up plain HTML and JS) create a new file called web.config and fill in the following:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;configuration&gt;
&lt;/configuration&gt;
</pre>
<p>Then add the following in between the configuration-tags, so your entire file looks like this:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;configuration&gt;
&lt;system.webServer&gt;
&lt;rewrite&gt;
&lt;rules&gt;
&lt;rule name=&quot;Proxy To External server&quot; stopProcessing=&quot;true&quot;&gt;
    &lt;match url=&quot;^services/(.*)&quot; /&gt;
    &lt;conditions&gt;
    &lt;/conditions&gt;
    &lt;action type=&quot;Rewrite&quot; url=&quot;http://my-external-server.com/{R:0}&quot; logRewrittenUrl=&quot;false&quot; /&gt;
&lt;/rule&gt;
&lt;/rules&gt;
   &lt;outboundRules&gt;
   &lt;rule name=&quot;Add Application prefix&quot; preCondition=&quot;IsHTML&quot;&gt;
        &lt;match filterByTags=&quot;A&quot; pattern=&quot;^/(.*)&quot; /&gt;
        &lt;conditions&gt;
             &lt;add input=&quot;{URL}&quot; pattern=&quot;^/(appName)/.*&quot; /&gt;
        &lt;/conditions&gt;
        &lt;action type=&quot;Rewrite&quot; value=&quot;/{C:1}/{R:1}&quot; /&gt;
   &lt;/rule&gt;
   &lt;preConditions&gt;
   &lt;preCondition name=&quot;IsHTML&quot;&gt;
        &lt;add input=&quot;{RESPONSE_CONTENT_TYPE}&quot; pattern=&quot;^text/html&quot; /&gt;
   &lt;/preCondition&gt;
   &lt;/preConditions&gt;
 &lt;/outboundRules&gt;
&lt;/rewrite&gt;
&lt;urlCompression doStaticCompression=&quot;false&quot; /&gt;
&lt;/system.webServer&gt;
&lt;/configuration&gt;
</pre>
<p>This configuration says to rewrite all requests coming into the virtual directory at <em>http://localhost/appName/services/</em> to <em>http://my-external-server.com/services/</em>. The outbound rule looks at the returned HTML and rewrites that too, so links and hrefs will continue to work. If you don&#8217;t do this step, links won&#8217;t be rewritten and when you follow them you&#8217;ll get an error because the links point to the server you&#8217;re trying to mask.</p>
<p>With this in place you can configure your Sencha Touch data classes to use <em>http://localhost/appName/services/</em> as the server prefix, and service calls will be proxied back and forth to your external data server. To make it easier to transition from development to production, wrap the server prefix in a configuration object.</p>
<p>I&#8217;ve found this proces to be of tremendous value when developing. It&#8217;s so much easier to debug things when they run in the browser and you can use the full browser stack.</p>
<p>One thing I&#8217;ve found is that sometimes IIS will barf and throw an internal server error related to request compression and GZip&#8217;ping. I&#8217;ve <a href="http://stackoverflow.com/questions/3713804/url-rewrite-outbound-rules-iis7/4363301#4363301">disabled Static Compression</a> in the hope that that would help, which it does. The error still shows up though. I&#8217;ve found that a quick &#8220;iisreset&#8221; does the trick and puts everything back on the track. This minor annoyance is worth it compared to the added benefit of running everything in the browser and skipping an emulator.</p>
<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fzianet.dk%2Fblog%2F2011%2F06%2F07%2Fjson-proxy-using-iis-reverse-proxy-for-fun-and-profit%2F&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"></iframe>]]></content:encoded>
			<wfw:commentRss>http://zianet.dk/blog/2011/06/07/json-proxy-using-iis-reverse-proxy-for-fun-and-profit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
