|
Introduction
Before the big boys finish their push servers and sell it for big money, why don't you write your own? What? You say you don't know low level HTTP, don't program C++, and know nothing about Windows NT services, not a problem. With Active Server and a little help from 15 Seconds you can have your own push server. The Active Server page code that we present in this article is not a hack nor a work-around. It is code that manipulates HTTP headers to make the client think that you are a push server. The client in turn calls Active Server pages that return the correct headers. Before we get started, you need to know something about Internet Explorer 4.0, the client that will hold up the other end of our push server example.
Channels
Channels allow the web author to define what his content includes and when it will be updated.
The Channel definition file (*.CDF) defines a channel. Channels consist of web pages, graphics and schedules. The graphics form buttons that are displayed in the channel bar, schedules which are automatically kicked off by the client based on instructions from the server, and web pages that are downloaded to the client when the schedule permits.
The Channel definition file is stored on the server as a .cdf extension, when downloaded, the browser reads the file and asks the user for their subscription choice. Within the file is the information the browser uses to schedule downloads, the pages to download and the graphics to put in the channel bar.
In a sense, a channel defines a way for the client to pull the web pages without the guidance of the user. On schedule, IE 4.0 pulls pages from the web server down to the user's local machine. When ever the user views the pages, they are always in the page cache and current. This way the web site appears fast. Secondly, users can view web sites offline without being connected to the network. Since the web site is already in the local cache the browser doesn't need to go out to web server for more pages.
CDF files are text files that are designed around Extensible Markup Language, XML. Like HTML, XML, uses tags, elements, and attributes. Because it is like HTML we can mimic a XML file with an Active Server Page.
Example 1
Here is an example of a simple Channel file:
Example1.cdf
<?XML version="1.0"?>
<CHANNEL
HREF="http://www.myserver.com/Example1.htm"
SELF="http://www.myserver.com/Example1.cdf"
PRECACHE="NO"
LASTMOD="1997.10.31T16:31"
>
<TITLE>Example 1</TITLE>
<ABSTRACT>Example 1 Channel File</ABSTRACT>
<SCHEDULE>
<INTERVALTIME DAY="7" />
</SCHEDULE>
</CHANNEL>
Notice that it looks a lot like HTML. Everything within the CHANNEL tags is the definition of one channel. The HREF attribute of the CHANNEL tag points to the web pages that should be displayed when the channel is selected. The SELF attribute of the CHANNEL tag point to the location of the CDF file. The PRECACHE attribute of the CHANNEL tag indicates whether the page referenced in the HREF attribute is cached on the client machine. In the example, the PRECACHE attribute is set to NO and the page is not cached. The LASTMOD attribute tells the client when the page indicated in the HREF attribute was modified last. This attribute supercedes the Last-Modified header of the page and can cause the star flag to appear in the channel bar indicating an update.
Take a close look at the CHANNEL tag, you will need to change the domain name to match your own server. Also notice the HREF, you will have change the domain name here to.
The TITLE tag is the title of the channel that is displayed in the channel bar and the ABSTRACT is the longer description that is displayed in the tool tip when the channel is highlighted.
The SCHEDULE tag defines when the browsers should return to the web site to see if there is updated information. The INTERVALTIME defines the time between updates. In this examples it is seven days.
In every seven days, all clients that are subscribed to this channel will request both the Example1.cdf and Example1.htm to see if they have been updated. If they have, then a red mark will be placed in the corner of the channel button indicating to the user that the channel has changed and they should go view it.
Push Server
Our definition of a push server is a web server that serves up different channel files to different users and those channel files define the web site differently. Sound familiar? When you create different web pages for each user it is considered personalization, and can be accomplished with Active Server Pages. Our design of a push server also uses Active Server pages to serve different channels to different users. The only difference is that the Active Server pages are returned pretending to be an XML file instead of an HTML file. We keep track of the user using cookies, which are nicely supported in Internet Explorer 4.0.
Example 2
For the first example we are going to create a clock channel that updates every minute giving the current time at the server. We will do this by creating a Channel definition file that subscribes to an Active Server page.
We can take the Example1.cdf file and modify it like below to create a Example2.cdf file:
Example2.cdf
<?XML version="1.0"?>
<CHANNEL
HREF="http://www.myserver.com/Example2.asp"
SELF="http://www.myserver.com/Example2.cdf"
>
<TITLE>Example 2</TITLE>
<ABSTRACT>Example 2 Channel File</ABSTRACT>
<SCHEDULE>
<INTERVALTIME MIN="1" />
</SCHEDULE>
</CHANNEL>
Notice that we have changed the HREF to point to an Active Server Page instead of a static .htm page. Also notice that we have set the interval time to one minute.
Now we have to create the Example2.asp file, here is the code:
Example2.asp
<%
' Get Local Date
dtModified=Now()
' Adjust From PST to GMT
dtModified = DateAdd ("h",7,dtModified)
strModifed= WeekDayName(WeekDay(dtModified),TRUE) &_
", " & Day(dtModified) & " " &_
MonthName(Month(dtModified),TRUE) &_
" " & Year(dtModified) &" "& Hour(dtModified) &_
":" & Minute(dtModified) & ":" &_
Second(dtModified) & " GMT"
' Set the Last Modified Header
Response.AddHeader "Last-modified", strModifed
%>
<HTML>
<HEAD>
<TITLE>Example 2</TITLE>
</HEAD>
<BODY>
<%=Now%>
</BODY>
</HTML>
The majority of the Active Server Page code is used to set the Last-Modified header. A technique that we illustrated in the Sep 11, 1997 Issue of 15 Seconds entitled: "The Last-Modified Header in ASP." When using Active Server pages with channels it is very important to set the Last-Modified headers. If you don't, Internet Explorer will not know that the channel has updated and can not inform the user. Static pages use the last modified date from the file for the Last-Modified header; Active Server pages by default do not return a Last-Modified header.
If you run download Example2.cdf file, creating a channel button, and then press the channel button, you will get the time on the server. In fact, pressing the channel button over and over will not update the clock. One of the reasons for this is that by default, Internet Explorer does not update channels while the user is on the computer. You can change this behavior in the properties of the channel, here is how:
- Open up Internet Explorer.
- Press the Channel bar button down so the channel bar is exposed on the left-hand side of the Internet Explorer window.
- Right click on the Channel Entitled: "Example 2."
- From the drop down menu choose Properties.
- Click on the Schedule tab. See Figure 1
Figure 1 Schedule Property
- Uncheck the box marked: Don't update this subscription when I'm using my computer
With this box unchecked the channel will update while the user is watching your pseudo push server.
This causes the file to update and the star indicator to appear in the channel bar indicating an updated channel. However, the page itself doesn't refresh. This is a limitation of Internet Explorer 4.0. If you want the page to refresh you will have to click on the channel bar again. Take note, the whole example fails without the page refreshing automatically.
Example 3
There is a difference between the first example and the second example which might not be apparent. In example one we included a LASTMOD attribute to the CHANNEL tag and in the second example there was none. Since the LASTMOD attribute on CHANNEL tag overrides the Last-Modified header sent back from the file referenced in the HREF attribute, if you are able to modify the LASTMOD date you do not need to return a Last-Modified header. However, in order to modify the LASTMOD date dynamically you need make the channel definition file dynamic.
The key to creating a push server out of Active Server pages is to make the client, IE 4.0, think that the pages are something besides static HTML. In other words, change the mime type from text/html to the mime type of the file that we are impersonating. The first file that we need to impersonate is the .cdf file. To do this we are going to send a mime type of application/x-cdf. Our example Active Server page would look like this:
Example3.asp
<%
Response.ContentType="application/x-cdf"
' Get Local Date
dtModified=Now()
' Adjust From PST to GMT
dtModified = DateAdd ("h",7,dtModified)
strModifed= Year(dtModified) & "." &_
Month(dtModified) & "." &_
Day(dtModified) & "T" &_
Hour(dtModified) & ":" &_
Minute(dtModified)
%>
<?XML version="1.0"?>
<CHANNEL
HREF="http://www.myserver.com/Example2.asp"
SELF="http://www.myserver.com/Example3.asp"
PRECACHE="NO"
LASTMOD="<%= strModifed %>"
>
<TITLE>Example 3</TITLE>
<ABSTRACT>Example 3</ABSTRACT>
<SCHEDULE>
<INTERVALTIME MIN="1" />
</SCHEDULE>
</CHANNEL>
Notice that besides the Visual Basic Script at the top of this page, it is very much like a regular channel file. In fact the browser will now think that it is a regular channel file thanks to the correct mime type. It is important to remember that the browser does not use the file extension, like the operating system, to determine the function of the file. The browser uses the mime type.
You can now remove the Visual Basic Script that creates the Last-modified header in the Example2.asp file. This is no longer needed since Internet Explorer now looks at the LASTMOD date in the channel definition file.
Example 4
Unfortunately that is not all you have to do to make a channel definition file out of an Active Server page. MDSN gives instructions to web server programmers that also apply in this case:
Optimizing Active Channels over HTTP
Web publishers are strongly encouraged to follow the size guidelines discussed in the Design Guidelines for Active Channels section. In addition to considering bandwidth issues, Web publishers should support the HTTP headers listed below to ensure efficient use of their site by eliminating unnecessary data transfer.
- Send a "Last-Modified" response header upon HEAD and GET requests. This allows the CDF client to monitor changes to the channel without downloading any resources.
- Use the LASTMOD= attribute on ITEM elements. This optimization technique prevents Internet Explorer from hitting the server to retrieve the last modified date for each item referenced in the CDF file.
- Use the "Expires" response header to indicate the lifetime of the resource.
- Don't send the "Pragma: no-cache" response header unless absolutely necessary.
- Support the "If-Modified-Since" request header.
As discussed before, review the techniques for setting the Last-modifed header from Sep 11, 1997 Issue of 15 Seconds entitled: "The Last-Modified Header in ASP." The Expires response header is discussed in Sep 20, 1997 Issue of 15 Seconds entitled: "Client Side Page Caching."
Here is the correct way to implement Example3.asp:
Example4.asp
<%
Response.ContentType="application/x-cdf"
' Get Local Date
dtModified=Now()
' Adjust From PST to GMT
dtModified = DateAdd ("h",7,dtModified)
strLastMod= Year(dtModified) & "." &_
Month(dtModified) & "." &_
Day(dtModified) & "T" &_
Hour(dtModified) & ":" &_
Minute(dtModified)
strModifed= WeekDayName(WeekDay(dtModified),TRUE) &_
", " & Day(dtModified) & " " &_
MonthName(Month(dtModified),TRUE) &_
" " & Year(dtModified) &" "& Hour(dtModified) &_
":" & Minute(dtModified) & ":" &_
Second(dtModified) & " GMT"
' Set the Last Modified Header
Response.AddHeader "Last-modified", strModifed
' Set Expires Header
Response.Expires=0
' Set Cache Control
' This only works on IIS 4.0
Response.CacheControl = Public
%>
<?XML version="1.0"?>
<CHANNEL
HREF="http://www.myserver.com/Example2.asp"
SELF="http://www.myserver.com/Example4.asp"
PRECACHE="NO"
LASTMOD="<%= strLastMod %>"
>
<TITLE>Example 4</TITLE>
<ABSTRACT>Example 4</ABSTRACT>
<SCHEDULE>
<INTERVALTIME MIN="1"/>
</SCHEDULE>
</CHANNEL>
IIS 4.0
If you are using IIS 4.0, you can impersonate a channel definition file (.cdf file) with an Active channel definition file (.cdx file). Files with the extension .cdx that are within an application scope return the channel definition mime type and execute under Active Server ISAPI. In other words by changing the file name of Example4.asp to Example4.cdx you can remove this line from the file:
Response.ContentType="application/x-cdf"
Summary
Because we can now impersonating a .cdf file using Active Server pages, we open ourselves to a lot of opportunities. The opportunities stem from the fact that the page is now dynamic and we can serve a different page to each individual.
In order to track the individual, we will need to issue them a cookie and write the cookie to the database. Along with the cookie we will need to write other information that pertains to the customer. For instance the last time they visited and the number of visits would be interesting in this scenario. However, issuing cookies and writing information to a database is not in the scope of this article. There is information on how to do this at:
Further Reading:
Download
You can download the examples in this issue:
http://15seconds.com/files/103197.zip 3K
|