As the team designs and determines the look of the UI and the type of interface to create, the development team will have to create actual UI for the application. As discussed in Chapter 5, the team should rely on prototypes to work with the user community to test and design the UI. Once the design is created, as discussed in Chapter 6 during the Planning phase, the team can take advantage of the Integrated Development Environment (IDE) to simplify the implementation process for native and Web-based applications. The IDE provide wizards, templates, and screen painters to help the team rapidly create the UI, which in turn interacts with the other portions of the user service layer.
Creating native UI applications varies significantly between development languages. Within the Microsoft IDE, UIs can be created with Visual Basic, Visual C++, or Visual J++. These UIs often rely on controls, code libraries, and operating system APIs supplied as part of the development language. As many multi-layer applications are being implemented with Web-based interfaces, we will not spend a significant time discussing creating native application UIs. However, for additional information, several other books can be used as references, such as the Microsoft Visual Basic 6.0 Programmer's Guide (Microsoft, 1998), Microsoft Visual C++ 6.0 Programmer's Guide (Microsoft, 1998), Desktop Applications for Microsoft Visual Basic 6.0 (Microsoft, 1999), Desktop Applications for Microsoft Visual C++ 6.0 (Microsoft, 1999), Visual Basic 6.0 Win32 API Tutorial (Wrox Press, 1998), and Essential Guide to User Interface Design: An Introduction to GUI Design Principles and Techniques (John Wiley and Sons, 1996).
Like any other enterprise application, an Internet-based application must often generate dynamic displays from one or more data sources. To help with the creation of this type of application, the development team can use the ASP component of IIS. With the release of IIS 4.0, ASP is also integrated with MTS.
A common error made by many new ASP developers is implementing too much business layer logic within ASP scripts. To scale applications and simplify script coding, developers should remember to implement business logic blocks as business-layer COM components.
In an Internet application, a Web browser displays an HTML-page-based user service layer. Requests from this layer transmit via HTTP to a Web server. In response to these requests from the client Web browser, ASP pages activate on the Web server. The ASP pages can dynamically generate HTML pages to be returned to the requesting browser. These ASP pages can be used to generate UI code to format and control the look and feel of the Web pages, thus ASP would be considered part of the user service layer. Also, the ASP pages can contain server-side script code that implements business logic, thus ASP pages can be part of the business service layer. However, the ASP pages should contain server-side script code that uses middle-tier business objects to do much of the work. The business objects might in turn call data access objects to access data sources in the data access service layer. Alternatively, the HTML and client-side script code used to generate the user service layer might be located within the ASP pages. Either way, ASP straddles the line between the user service layer and the business service layer.
ASP offers developers several advantages by addressing a number of issues and complications that arise during the development of high-quality, high-performance Web sites.
Familiar Programming Model
A major advantage of ASP is its familiar programming model, which closely resembles HTML but is augmented with scripting. Server-side scripts can be written in any language, as long as a corresponding scripting engine is available. IIS includes scripting engines for Visual Basic Script and Microsoft JScript, which is based on (ECMA) script.
In general, server-side ASP code should defer complex algorithms to COM components, and code that simply calls multiple COM objects to perform work should be placed in a COM component. Because ASP script code is interpreted at run time, less script interpretation results in more effective development performance. On a technical level, ASP code can use only the IDispatch interface to access Automation components. Business objects are compiled and can usually take advantage of vtable-binding, generally providing improved performance over ASP code's use of IDispatch. Additionally, business objects can be reused in other applications, such as a Win32-bit client version.
ASP runs on a Web server and controls exactly what gets sent back to the Web client, thereby protecting intellectual property—data or code. Client computers cannot track the data's location or the origin of the generated HTML. This protective mechanism provides a layer of security abstraction that many applications can utilize with an appropriate design.
Browser and Display Variations
In addition to browser differences, the wide variation in screen resolution and display colors can make it difficult to create Web pages that work well for all users.
ASP also addresses the need to generate Web content dynamically, as well as statically. Dynamic content is normally generated from one or more server-side data sources, which should not be directly accessed by client computers. For one thing, per-client connections don't scale very well. More importantly, security issues arise when random Internet users are given access to corporate databases. As a result, Internet applications are usually structured so that a secured server-side application can generate HTML pages containing data to be displayed. Whenever a Web client needs more data, the Web server receives a new request, and the server-side application then generates a new Web page.
ASP alleviates dynamic content issues by mixing server-side scripts and client-side content. Accessing an ASP page triggers execution of server-side scripts on a server. When these scripts are executed, an HTTP response is generated and sent back to the client. Server-side scripts can control the HTML statements (coded in .asp files) included in such responses; or these scripts can generate HTML statements on the fly. ASP pages provide a straightforward manner in which to handle various browser capabilities and to display conditionally different information according to the features supported by the requesting client.
With the advent of Java applets, ActiveX controls, DHTML, and ASP pages, it is now possible to write client-side Web applications that maintain some connection to a server. Instead of forcing a new page to be generated whenever more data is needed, data is transferred between scripted client-side components and a server-side application. Internal data sources do not need to be exposed on the Internet because they are accessed only by server-side applications.
ASP provides several standard Automation components to help with common Web tasks, such as determining browser characteristics, parsing parameters and cookies in a page request, or sharing information between pages in the application. ASP's support of Automation components, which are compatible with server-side scripts, makes it relatively easy to write pages to process HTML forms. In addition, complex operations can be coded once in custom components, and later reused in many server-side applications.
ASP provides a powerful way of bridging the gap between client-side presentation logic and server-side business logic in three-tier Internet applications. With IIS 4.0, ASP is fully integrated with MTS. MTS provides process, thread, and other resource management services to IIS and ASP applications, and allows pages in an ASP application to be marked as transactional, giving each page all the benefits of transactions.
The server-side script in an ASP page is often considered the first layer of business logic. This layer might use several COM objects to satisfy a request. Transactions can be used to help ensure that resources are updated correctly when multiple objects work together to fulfill a client request. IIS 4.0 allows any ASP page to be processed within a transaction. When a page is processed, a new transaction is created. All the objects created within the page are automatically enlisted in the transaction, if appropriate, by MTS. The transaction terminates when the entire file has been interpreted and any server-side scripts have executed. If the transaction aborts, all of the resources in the transaction roll back to the values they had before page processing began. Because the development team is creating a Web-based application's design, this roll back capability is particularly useful for pages that update databases.
IIS uses MTS to manage server application processes. Each application, denoted by a unique virtual directory, can be configured to run in the main IIS process or in a specific MTS process. Such a process can improve overall server reliability. If one application fails, only that application is shut down and restarted. Shutting down the application does not negatively affect other applications, or more importantly, the entire Web server.
Separating applications into individual processes also helps with server maintenance. If an application needs to be updated, only that application process needs to be shut down, and the entire Web server, as well as other server applications, can continue to run.
MTS manages all application processes. However, an IIS configuration setting can create a specific IIS application. An IIS application's management is encapsulated by a COM component called the Web Application Manager (WAM) before being controlled by MTS. The WAM is responsible for loading the ASP run-time and other DLLs, and communicates with these DLLs whenever an HTTP request is received. Whether running in IIS or in another process, each application contains an instance of the WAM object. When IIS is configured to run an application separately, developers can call on MTS administrative objects to:
Applications configured to run in IIS are registered in a default MTS in-process package. When IIS receives an HTTP request, it determines whether or not the requested Uniform Resource Locator (URL) is designated as an IIS application. If so, IIS looks in its internal WAM map to locate the correct WAM object. If the application isn't running, its WAM won't exist and will have to be created. IIS creates the WAM object using the application-specific GUID generated at registration time. At this point, MTS starts a new process, if necessary, and begins managing objects and resources for the application. If the requested URL is not part of an application, it is processed within the default IIS application space.
As we discussed, ASP pages can be used to call the business objects from the server and return Web pages to the client. ASP pages contain a combination of directives, script, and text. Directives and script are delimited using the characters "<%" and "%>". The <SCRIPT> tag can be used to mark a block of server-side script. Any element other than a directive or server-side script is displayed as-is in the Web page returned to the client.
ASP page scripts are executed when the page request is received from the client. Objects created by the scripts exist only for the duration of page processing, unless explicitly saved in Session or Application variables. Saving objects in these variables may limit scalability or affect dynamic load balancing, and these implications should be considered carefully before saving objects.
Within the scope of a page, developers can create whatever objects they need to perform page work. However, as we've already said, as much business logic as possible should be encapsulated in components, rather than using script code. Server-side script should focus mainly on calling business objects and creating Web pages to be returned to the client computer.
When transactions are used, the page processing defines the transaction boundary for all objects created by the page. If any object aborts a transaction, an error page can be returned instead of the requested page. To mark a page as transactional, use the TRANSACTION directive in the first line of the page's code, as shown here:
The OnTransactionCommit and OnTransactionAbort events can be used to return different information to the client, depending on whether the transaction committed or aborted.
The CreateObject method is used in a server-side script to create objects, ensuring that the objects are created within proper transaction context, and that access to ASP-intrinsic objects, such as Response and Request, is available. To abort a transaction from within a server-side script, call the ObjectContext SetAbort method.
ActiveX components are small COM components sent to the client from the ASP pages. Client-side ActiveX components can be used with client-side scripts to perform user service and business services. Using an ActiveX component with client-side scripting is no different than using remote business objects. (We discuss remote data objects in further detail in Chapter 9.) However, if developers are creating components to be used from client-side applications, they need to pay special attention to the code security and download issues described earlier.
When using Internet Component Download to download and install client-side application components, the components should be packaged in a self-installing executable or .cab file, according to guidelines in the Microsoft Platform Sofware Development Kit (SDK) Internet Component Download documentation. The downloadable file should be digitally signed so that users can verify that the file comes from a trusted source and has not been violated. All DLLs on which components rely should be included or referenced in the download package. Development tool documentation should identify the DLLs required by tool-generated components. Such documentation could also provide instructions on how to package these components for downloading.
Regardless of whether or not these components are downloaded, verify that they are safe for scripting and initializing. As mentioned, some browser configurations may prevent unsafe components from being created or scripted. Registry entries can be used to mark components as safe for scripting and initialization, or the IObjectSafety interface detailed in the Platform SDK can be implemented.
The key point to remember in accessing native applications is the application relies heavily on the underlying operating system. For Windows applications, the application's executables, DLL, and additional application code must be accessible and known to the client operating system. The application is typically started using an icon or through the operating system's program menus. For the application to be accessible, it is critical the application's installation and configuration routines are executed properly on the desktop computer.
It is important to understand some basics of Web server and browser access. Most Web applications are accessed through a browser and a display name in the form of a URL. The display name leads the browser to an IP address, typically by means of a Domain Name Server (DNS) lookup. After the IP address is located, a TCP/IP session is established with the Web server using an HTTP communication protocol.
With older browsers or those not using HTTP 1.1 or later, each picture, page, control, and applet are separate HTTP requests, and therefore separate sessions. Each time a session is established, it requires processing, time, and bandwidth overhead. Browsers using HTTP 1.1 or later can be configured to perform multiple HTTP requests within a single session, thereby decreasing load time and communication overhead.
The client computer stores the resolved DNS name and the appropriate TCP/IP address in the computer's memory for a fixed period of time (determined by the user). The next time the URL is requested, the browser first looks in memory for the appropriate IP address. If the name is no longer stored in the client computer's memory, the DNS name lookup is retriggered.
In the early days of statically written Web pages, scaling Web servers was a simple process. Mirror sites hosting identical content would be created on two or more Web servers. Each Web server had its own TCP/IP address, as shown in Figure 7.1. A DNS naming technique called round-robin DNS assigned all the TCP/IP addresses to a single display name. Each time the DNS server received a name request, it provided the TCP/IP address of the next server in an ongoing loop. Thus, access was evenly allocated across all servers, allowing these servers to share the request-processing load using a method known as load balancing. An additional result was that a client computer couldn't determine which server it would access when it requested the Web page's URL.
Figure 7.1 Web server configuration using Windows Load Balancing Service
Currently, dynamic pages and typical Web page scripting prevent this round-robin load balancing from working properly. Web servers maintain ongoing sessions, and many pages apply session variables that are used throughout a client computer's interaction with a Web server. Because a client computer might not always return to the same Web server over a specific period, round-robin load-balancing does not work with most session-oriented Web sites. If the client computer later accesses a different (mirrored) server, the mirrored server doesn't have any information about the client computer's previous session and might not recognize the authentication, causing a page request to fail.
A simple solution to this problem is to ensure that, for a period of time, a client always returns to the same server. With so-called sticky connections, the client computer resolves a URL to a single TCP/IP address allocated for all the Web servers. This central TCP/IP address is an intermediate address that controls specific servers to which actual page requests are sent. Logically, intermediary TCP/IP addressing resembles the diagram in Figure 7.2. Incoming requests are directed from the intermediate server to a new server. Repeat visitors are directed to their specifically allocated server.
Figure 7.2 Adding Web servers to improve performance
Microsoft provides the Windows Load Balancing Service (WLBS) and Cisco Systems provides LocalDirector to maintain sticky connections for clients and to add fault tolerance. The WLBS system continually monitors Web servers to determine whether a server becomes non-functional, ensuring that page requests are not sent to a defunct server. To add additional Web server processing, a new mirror server is configured and simply added to the Web server WLBS cluster.
These scaling technologies allow the Web-based UI to continually increase the number of concurrent clients being served without requiring a significant re-design of the Web-based application code.