Coding the Subservient Programmer
Overview
|
Our Subservient Programmer was created using Visual Studio Express - C#, Visual Basic and Visual Web Developer flavors. When the application is idling, you can see the programmer working at his computer. After entering a command phrase, such as “test”, the programmer will be shown doing your bidding. Once the programmer has completed the task, he will resume working at the computer as he was before and allow you to enter another command. So where does an idea for something like this come from? A couple years ago, a creative group of marketing types decided to create a Subservient Chicken that would perform tasks based upon user input. Judging by the reported traffic generated from the site, people found the application quite amusing. Feel free to experiment with the chicken to get an idea of its functionality. |
Screenshot 1 - Programmer testing an application |
Desired Functionality
|
One of the primary goals with this project is to present a seamless experience to the end-user - one that is simple and entertaining. Before we get into the implementation details of the Subservient Programmer application, let’s go ahead and take a moment to play with the end result. Download the example code for the project (either C# or VB.NET) and locate the solution file for the Windows Forms version of the application. You can open the solution in Visual Studio 2005 Express Editions which are free to download. To get the application started, press F5 and then submit a command by typing it into the provided text box. Once you press the Dispatch button, the subservient programmer will be contacted and a response will be played as video. You many notice that commands you have not entered before will require more time for ‘contacting’ the programmer (or downloading a video from a server). If you enter the command again, the programmer will respond much quicker than before since you have ‘trained’ him (or locally cached a video). |
||
Screenshot 2 – Programmer dancing |
Screenshot 3 - Programmer fixing computer |
|
The Subservient Programmer application was designed to be able to operate in both an online and offline mode. When online, the application makes all movie clips offered by the server available to the user, downloading and caching responses when needed. If the application goes offline, the application will be aware of that situation and simply use only local videos from the cache. Commands that would otherwise be valid will be met with a confused response by the programmer rather than an error. In addition to the Windows Forms version of the application there is also a Web application that provides the same functionality. You can try this version out by first opening the solution containing the Web source and then pressing F5 to launch the site with the ASP.NET Development Server. You should be presented with the default page for the website which allows users to choose their experience. Either the Web application or the Windows Forms application can be chosen. The Windows Forms version is labeled ClickOnce because that is the method used for deployment. ClickOnce allows a user to easily download and install the application to their local machine. In the next section we will introduce the overall architecture of the Subservient Programmer experience. |
||
Screenshot 4 - Subservient Programmer default page showing requirements and options |
Screenshot 5 - The Subservient Programmer Web application |
Subservient Architecture
|
At this point you should be somewhat familiar with the user experience provided by the Subservient Programmer application. Now it’s time to take a look at the magic behind the scenes. As you read through this section, try to think of some ways that you could improve or adapt the application for your own project. There is a definite need for the separation between the application logic and the movie data itself. This enables the initial installation of the Windows Forms client application to stay small and allows the movie content to be periodically updated or added to without having to update the client application. As an example, let’s say that you develop the content for and deploy a Subservient Squirrel. To get users hooked, or at least satisfy their need for instant gratification, the initial download should be quick, painless, and allow them to issue a command to gather nuts right away. Somewhere down the road you may notice that many users want the squirrel to dress up in a pink tutu. Even though you never anticipated the request, you can still create the content and add it to the server. When the next request comes in for a squirrel in a pink tutu, it will be returned automatically. On each client machine there are two options for interacting with Subservient Programmer as we have already seen; the Windows Forms application and the Web application using Internet Explorer. Take a look at the following diagram to get an idea of how the overall system works. |
Figure 1 - Overall Subservient System Architecture |
|
The Windows Forms application interacts with the server in two ways. The first is to keep a local copy of the available movie list and associated keywords in sync with the version on the server. To do this, a web service method is made available which returns the timestamp associated with the movie list file on the server. Updated movie list files can then be downloaded using a WebClient object. The Windows Forms application will process commands and translate them into video clips to be played locally, requesting clips from the server if necessary. Using the Web application with Internet Explorer provides the same functionality, except this time most of the translation work is done on the server side. For demonstration and learning purposes, putting the Web application, service, and movie content on the same server is just fine. However, if you wanted to actually deploy something like this you would need to consider how to scale out in order to handle lots of activity. One thing that you could easily do is put the movie content on a separate server, and the example code base already enables that with a configuration option. |
Associating Commands with Movie Clips
|
One of the first steps in creating the infrastructure for an application like this is to devise a method to associate the various user commands that you expect to receive with the video content. The easiest way is probably to manually map keywords and phrases to videos when they are created that best describe the actions seen in the video. Some video content may be generic enough to warrant having multiple keyword definitions. For example, any command that includes the word “hi”, “hello”, “wave”, etc. will have the programmer look at the camera and wave his hand. A default clip that has him shrugging his shoulders will be returned whenever the virtual programmer does not have a match for a user command. All of the keyword mappings need to be associated with the filenames of their respective movie clips. Subservient Programmer uses an XML file to keep track of movie clip information. This file is included with the Windows Forms application, but as we discovered in the previous architecture section, we can contact a web service to see if a new server version has been published and then download it if necessary. The XML file, named movieclips.xml, is located in the EmbeddedClips directory of the ClickOnce application, and in the Clips_Small directory on the server. Go ahead and load the movieclips.xml file and take a look at the format. To the right is a small sample clip to take a look at in case you have not downloaded the full source. |
<?xml version="1.0"
encoding="utf-8" ?>
|
|
As you can see from the sample movie clips XML above, defining movie clips is fairly simple. At the very beginning of the file we have a ‘last_updated’ value which is part of the MovieClips node. This contains the published timestamp information for the file. Next, all of the MovieClip nodes are defined, one for each movie file. Each MovieClip node has a unique number, a list of keywords, and the name of the movie clip. The keywords are defined in a comma separated list and the only time white-space is used is when multiple words are used to define a single keyword phrase. |
Translating Commands into Movie Clips
|
Most of the subservient magic happens after the user types in a command phrase and presses the Dispatch button. To start with, the entire user command is compared to each keyword list item for the first movie clip. If a match is found, then the proximity to the beginning of the keyword list for the particular movie clip is noted for future reference. By default, the search will continue until we have examined all movie clips and their list of keywords. The best match, defined as the one having the closest proximity to the beginning of the keyword list, will be chosen as the best response. For example, if there is a clip that has the keyword “wave” listed as its third keyword and a later one that has “wave” listed as its first keyword, then the later one will be considered the best match. Note: The application configuration file contains a key that allows you to adjust a shortcut threshold value. By default, it is set to -1, which means that no short-circuiting of the keyword search operation will occur. However, if you set it to a valid proximity value of 0 or more, the search will stop as soon as a match is found that is at least that close to the beginning of a keyword list. If an exact keyword match can not be found, then the subservient code will break down the command phrase from the user down into individual words, testing each one for an exact match as before. The one with the closest proximity to the beginning of the keyword list will be considered the winner. For example, if the user enters the command “eat cheese”, the application will not find an exact match for the entire phrase. It will then do a search for “eat” and “cheese” individually to determine if there is an appropriate response. |
Configuring the Subservient Applications
|
Both the Windows Forms application and the Web application have XML configuration files that can be used to adjust various application settings. Let’s take a look at the configuration file for the Windows Forms application, which is located in the SubservientProgramer.exe.config file. |
|
<configuration>
|
|
Two important configuration items that may change depending upon where the remote videos and Web service are located include the remoteUrl and SubservientWSUrl keys. This allows you to update these URLs without recompiling the application. The Web application has many of the same application setting keys that we just saw, but it also contains a key that enables or disables logging commands to a SQL database. This feature is turned off by default, but it could be used to help determine which commands are popular but do not have an appropriate video yet. The settings for the Web application are located in Web.Config. |
Deploying the Subservient Web Application and Service
|
As you have already seen, testing the Web application and service within Visual Studio or Visual Web Developer Express is as easy as pressing F5. However, you may want to deploy the site to a production Web server at some point. In this section, we will highlight the steps necessary to get the Subservient Programmer website up and running. If you want to deploy the website to your development machine, there are a few requirements that you need to keep in mind:
Follow these steps to configure the Subservient Programmer website: |
Note: Be aware that the impersonation information is stored in the Web.Config file for the application, which is stored as plain text. Now test the subservient website locally to verify that application is set up and working as expected. To do this, open up Internet Explorer and navigate to http://localhost/SubservientProgrammer/. You should see the default web page load which gives you the option to use the Web application or install the ClickOnce application. Verify that the browser based application works by entering a test command and viewing the response. If local impersonation is not used for the application, it will be unable to download the needed video clips from the remote server. Note: You may also need to configure Windows Firewall to allow HTTP traffic to make the website accessible to other computers. To deploy the website to a remote server, select Website | Copy Web Site from the main menu (of Visual Studio or Web Developer Express). Next, select the Connect button near the top of the page displaying the Source Web site and Remote Web site information. The following dialog box will appear: If you have a Web hosting account, you may deploy using the FTP Site option or the Remote Site option. The Remote Site option requires that the server has FrontPage Server Extensions installed. See the publication requirements and documentation of your website host for more details. Note: In Visual Studio 2005, you have another option which is referred to as publishing which is available to you in the Build menu. Publishing differs from the type of deployment that we saw earlier in that source code is precompiled. Even the .aspx pages can be precompiled if you so choose. Visual Web Developer Express does not provide this option. |
Creating the ClickOnce Installer
|
The Web application example already includes a copy of the ClickOnce files for the Windows Forms application, which can be deployed as-is to a web server. However, if you make any changes to the Windows Forms application, you will need to re-publish the ClickOnce files to the server. To publish the ClickOnce files, select Build | Publish from the main menu of either Visual Studio 2005 or an Express product and follow the publishing wizard. |
|
|
Select the location where you would like to deploy the ClickOnce files. If you have set the application up on your local machine in an IIS virtual directory, select that location. If you are deploying to a remote server, select that location. Make sure that you deploy the ClickOnce files to the ClickOnce directory for the Web application, wherever it is located. Select Next to finish selecting the deployment location. This will bring up the window where you specify how users will install the application. Select the option that says “From a CD-ROM or DVD-ROM” radio button. You could enter the specific URL/path where the ClickOnce application will be installed from, but this will bind it to a specific URL/path that cannot be changed without reconfiguring and repackaging. For the purposes of this example we choose the removable media option because it allows the application to be installed from anywhere. Select Finish to complete the publication process. If the publication is successful, try installing the Subservient Programmer application via the deployed website. |
Summary
|
The Subservient Programmer application, which includes both a Windows Forms version and a Web version, allows users to issue commands to a virtual programmer and see the response as if he was actually being directed. The client application is kept up to date on the available movies and associated keywords through the use of a Web service. Video responses are downloaded from a remote content server and then played for the user. You can take the examples provided and add new content to create your own subservient entity. The most time consuming part will be creating the videos that represent the possible actions for your entity. When creating the videos, try to stay consistent with the background, lighting, and starting and ending points for your entity - this will help keep the illusion that the video is live. Next, you need to generate the movieclips.xml file which includes the keywords for each video. Changing the UI graphics for the client applications (Windows and Web) is easy to do using the designer in Visual Studio or Express. Finally, deploy your subservient application for the world to enjoy, or at least your friends. |