CallXML 3.0 Development GuideHome  |  Frameset Home

  tutorial Hello World with ASP  |  TOC  |  A: Audio Files & CallXML  

Tutorial: "Hello World" with Cache Control


Some words about cache control


One of the first problems we as developers will encounter when scripting applications to work on the phone, is the ubiquitous issue of caching. Few things are as annoying as calling up your super-cool script and hearing the cached version from three days ago. Great embarrassment can occur when you still hear the scratchy recordings your little brother made at 4:30 AM, instead of the professional quality voice talent that you spent several grand on to impress the boss, while you are demonstrating your application to the Board of Directors. On a normal website, clearly the cache is simple enough to overcome by manually clicking on "Reload" or "Refresh"; but how do we do this on the phone?

Turns out, the masterminds behind the internet already recognized this as a problem before we came along. In the same way that we use normal "web" methods to code our telephone applications; we can also use normal "web" methods to control the caching of our telephone applications. Remember that caching offers the dichotomy of dramatically increased performance versus the potential for out-dated code/media being used. It comes down to speed vs. functionality, and it doesn't get any more basic than that.

There are at least two levels of caching at play in any telephone application. The first is the actual internet-based fetching of the application/web-page itself. This is not a callxml issue. Until the web-page is fetched, it is a 100%, grade-A, choice cut, web-server issue. To put it another way, until the web-page is fetched, it is a 100%, grade-A, choice cut, web-server issue.  The second caching level occurs once the application/web-page has been fetched and media elements are being loaded from the server. This is a callxml issue and can be controlled from within the callxml scope. Let's explore this level of caching first, and then step back and examine how we can interact with the server to control caching on the application level.


Step 1: Cache control for media elements


So what is a "media element"? For our purposes, we are referring to anything that your callxml application would have to load from a server directly; that is, any audio file or URL. So the internal cache control method is as follows: any callxml element that loads a URL or an audio file accepts an attribute called "cache". This list includes:

The cache attribute has a simple value of "YES" or "NO", with the default being "YES" (i.e., enable caching). So if you want your application to avoid caching every audio file in your script, simply include the cache attribute with a value of "NO" at every occurrance.


    <playaudio value="helloworld.wav" format="audio/wav" cache="NO"/>
    <playaudio value="greeting.wav" format="audio/wav" cache="NO"/>
    <playaudio value="mainmenu.wav" format="audio/wav"/>

    <goto value="mynextpage.xml" submit="*" method="get" cache="NO"/>


Notice that we have four elements in the above code snippet that involve caching. Our first two <playaudio> tags are ignoring any cached version and loading the "helloworld.wav" and "greeting.wav" audio files directly from the server each time the application is run (perhaps these two files are dynamic and frequently change). Unlike them, however, is the file "mainmenu.wav" in which we tell callxml to go ahead and use caching (notice that we did not explicitly tell it to use caching -- callxml defaults to caching). Our fourth example element is a <goto> tag, which is loading the next script page in the application's sequence. Here we tell it to not use cache, in case we made some script-level changes. This is identical to setting the HTTP header "Cache-Control: no-cache", which is what we were alluding to earlier when we discussed "non-callxml" caching methods.


Step 2: Cache control at the script-level


Well, since the cat is out of the bag, we might as well open a can of tuna fish... Standard web page caching can be controlled through the header that is passed into the server. If your code contains an HTTP header with "Cache-Control: no-cache", it will skip past any available cached version and load directly from the web server. You can actually do all kinds of nifty things using HTTP cache-control headers, if you are so inclined.

So now the question becomes "How do I alter the HTTP header?" Since we are using XML (specifically CallXML), the answer to that question depends on the server-side scripting language you are using to output the XML. If you are using straight callxml, then you will have to rely on the techniques from Step 1, but if you are using a back-end scripting language, you can programmatically adjust the HTTP header info.

In PHP, it would look like this:

<?PHP
  header ("Cache-Control: no-cache");
  ... body of code here ...
?>


In ASP, it would look like this:

<%
  response.Expires = -1
  ... body of code here ...
%>


In ColdFusion, it would look like this:

  <CFHEADER NAME="Cache-Control" VALUE="no-cache">
  ... body of code here ...


In JSP, it would look like this:

<%
  response.setHeader("Cache-Control","no-cache");
  ... body of code here ...
%>


In Perl, it would look like this:

  print "Cache-Control: no-cache";
  ... body of code here ...


These are the most basic web techniques for controlling cache. Experienced web designers can tweak the expiration header tag to load the application without cache after a specific length of time and this will also work for telephone applications. It may also be worth noting that these techniques assume you are using an HTTP 1.1 compliant server. The syntax will be different for HTTP 1.0 servers. For example, in PHP the header function call would look like this instead:


<?PHP
  header ("Pragma: no-cache");
  ... body of code here ...
?>


Not sure if you set those cache headers correctly with  your ASP code? Run your URl through the Cacheabilty Engine Query to find out for sure!

Step 3: Actual application with cache-control

Let's look at a simple simple server-side application, (detailed completely in the next Lesson). We have an initial file that gathers a key press. Let's add some cache control to this file:

<?xml version="1.0" encoding="UTF-8" ?>
<callxml version="3.0">

  <do>
    <playaudio value="helloworld.wav"
              choices="*,#"
              cache="no"/>

    <on event="choice:*">
      <goto value="helloworld-handler.php?key=star"
          submit="*"
          method="get"
          cache="yes"/>
    </on>

    <on event="choice:#">
      <goto value="helloworld-handler.php?key=pound"
            submit="*"
            method="get"
            cache="yes"/>
    </on>

  </do>

</callxml>


Here we are using cache for the <goto> calls, but not for the <playaudio>. Now let's code the PHP script:


<?PHP
  header ("Cache-Control: no-cache");

  $s = $HTTP_GET_VARS["key"];

  echo "<?xml version="1.0" encoding="UTF-8" ?> ";
  echo "<callxml version="3.0"> ";
  echo "  <do label=" $s "> ";

  if ($s == "star") {
    echo "    <say>you pressed the star key.</say> ";
  } else {
    echo "    <say>you pressed the pound key.</say> ";
  }

  echo "  </do> ";
  echo "</callxml>";

?>


While the page that calls this PHP script said to use cache, we over-ruled that directive by manually informing the web-server to not use cache inside the script. Pretty simple, isn't it?




Step 4: Upload, and try it out


Your "Hello World" with Cache Control is now done. Call the number associated with your callxml application, and you'll find that the results of this tutorial work just like the previous ones. Except now, we have at our disposal control over caching mechanisms.


  CallXML 3.0 source code.


What was just covered




  ANNOTATIONS: EXISTING POSTS
0 posts - click the button below to add a note to this page

login
  tutorial Hello World with ASP  |  TOC  |  A: Audio Files & CallXML  

© 2008 Voxeo Corporation  |  Voxeo IVR  |  VoiceXML & CCXML IVR Developer Site