|
|||||||||||||
|
|
|
|
|
|
|
|
|
||||||
|
|
|||||||||||||
![]() ![]() ![]() ![]() ![]() ![]() |
An AllegroServe based Web Application FrameworkHaving deployed a number of Web applications internally, we have found that each contained a number of similar features. We feel that these would be valuable additions to any web application. The features discussed below have been packaged into a web delivery framework that includes a simple server application and is available for download. Table of Contents
Feature OverviewThe Web Framework is built with the following requirements in mind:
Download and InstallationThe Web delivery sample framework is available for download here: ( tgz | zip ) To install, simply extract the archive to your local filesystem. Once that's done, start up lisp and load the server framework. We include a small sample website that fetches weather data for select locales via ftp from the National Oceanic and Atmospheric Administration (NOAA) and displays it. To load the sample server into your development image, evaluate the following: user(1): :cd /path/to/www-demo/ user(2): (load "load.cl") To start the server simply call the function cl-user::init-server. It accepts a single numberic argument, specifying that port on which the server will listen. You will need to choose a port that is available and that the operating system will permit you to use. Web servers normally listen on port 80. On unix-like systems (macosx included) port 80 can only be allocated by the the superuser (called root). On windows any user can open port 80 as long as it's not yet allocated. In order to make this tutorial work on both Unix and Windows (and not require that you run as root on Unix), we'll put our web server on the localhost at port 8000. IDE and Express users should note that the default package when using the IDE is the :cg-user package, while this module uses the :cl-user package. This article will use full symbol names to facilitate your ability to cut and paste user(3): (in-package :user) #<The common-lisp-user package> user(4): (cl-user::init-server 8000) When this returns, you have a running server. Try visiting it from a web browser by navigating to http://localhost:8000/. You should see a weather report for Oakland, CA and San Francisco, CA. Our sample weather portal works by using an ftp client to retrieve weather data from tgftp.news.noaa.gov. Each location is given a 4 letter identifier and is updated roughly hourly. A "Weather Monitor" process is started, which runs every hour (or on a forced reload) to update locally stored information about a particular region. We pass a variable containing a list of string identifiers, representing cities, to the weather monitor, for which it will maintain data. This variable can be updated through the publish.cl reload procedure, or by directly modifying it's value via the telnet service, and the new areas will be included in the servers output the next time the monitor updates or a reload request is made on the reload-server. The web interface for the weather reporting can be found in src/publish.cl. The code for fetching each weather report can be seen in src/weather.cl Now modify publish.cl. Reverse the comments on the following two lines at the end of the file and save it.
;; (defparameter *weather-sites* '("koak" "ksfo" "knuq" "kapa" "kbwi" "oakb" "ybrm"))
(defparameter *weather-sites* '("koak" "ksfo"))
Now visit http://localhost:9000/reload. This forces a reload of publish.cl and should update the list of weather sites. When you visit http://localhost:8000/ again, you should see weather reports for a few other places around the world. Additionally, you can modify the variable *weather-sites* by telnet'ing into the server and changing it directly. From a shell or your preferred telnet app, try to connect to the server:
% telnet localhost 8889
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
WARNING: do not use :exit or (exit). You will kill the web
server if you do. Use (quit) to quit.
cl-user(1): *weather-sites*
("koak" "ksfo")
cl-user(2): (setq *weather-sites* '("koak" "ksfo" "knuq" "kapa" "kbwi"))
("koak" "ksfo" "knuq" "kapa" "kbwi")
cl-user(3): (cl-user::quit)
Connection closed by foreign host.
If the value of *weather-sites* does match the transcript above, you'll see a number of unknown places added to the output. This is because the "weather monitor" process has not yet fetched information for these locales from the weather service. You can issue a reload request to force the Monitor to update, or you can call a function to do so.
% telnet localhost 8889
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
WARNING: do not use :exit or (exit). You will kill the web
server if you do. Use (quit) to quit.
cl-user(1): *weather-sites*
*weather-sites*
("koak" "ksfo" "knuq" "kapa" "kbwi")
cl-user(2): (weather-monitor)
(weather-monitor)
nil
cl-user(3): (quit)
(quit)
Connection closed by foreign host.
Another refresh of the main page http://localhost:8000/ and the unknown locations will now be known. Building a Standalone Web ApplicationGenerally, you will not run your server from a development image. Instead, you'll want to create a standalone web server. The file build.cl takes care of this. To create a standalone app, evaluate the following: user(1): :cd /home/demo/www user(2): (load "build.cl") Simple! Upon completion, there will be a dist/ subdirectory containing the runtime application. The binary executable to invoke the service is named sample-server. The command-line arguments differ between mswindows and non-mswindows versions and are detailed below. Command-line Arguments (Windows)The windows version of the framework makes use of the ntservice module available at http://opensource.franz.com/. You are encouraged to read the documentation for this module. In particular, the readme file has useful information about programs run under the "LocalSystem" account and how service behavior may differ on Windows Vista (which we include below). Usage: sample-server --register [--interact-with-desktop] [--port port] [-o logfile] sample-server --unregister sample-server --start-service sample-server --stop-service sample-server [--port port] [-o logfile] [--interact-with-desktop] [-d]
Some sample invocations of sample-server would appear as follows: ;; register a service to run on port 8000, logging to sample-server.out % dist/sample-server --register --port 8000 -o sample-server.out ;; unregister the service % dist/sample-server --unregister ;; re-register to a different port, default logfile, interact with desktop % dist/sample-server --register --port 8888 --interact-with-desktop ;; start the service % dist/sample-server --start-service ;; stop the service % dist/sample-server --stop-service ;; debug mode! this will drop you into a toplevel break loop. % dist/sample-server --port 8000 -d Command-line Arguments (Non-Windows)Usage: sample-server [-d] [-D] [-o logfile] port -d -- debugging mode -D -- daemon mode -o logfile -- log standard output to this file, or www.out if not given port -- the port on which we listen Using the build application on unix is easy. Here are some sample invocations: ;; start a detached server running on port 8000 % dist/sample-server -D 8000 ;; start a detached server with output to sample-server.out % dist/sampler-server -D -o sample-server.out 8000 ;; start up in debug mode. You'll drop into a toplevel break loop. % dist/sample-server -d 8000 As always, we encourage you to examine the code. If you have any questions or problems with the application, please email us at support@franz.com
© 2008 Franz Inc - Privacy Statement |