A computing system that is composed of two logical parts: a server, which provides services, and a client, which requests them. The two parts can run on separate machines on a network, allowing users to access powerful server resources from their personal computers (Fig. 1). See also: Local-area networks; Wide-area networks
Client-server systems are not limited to traditional computers. An example is an automated teller machine (ATM) network. Customers typically use ATMs as clients to interface to a server that manages all of the accounts for a bank. This server may in turn work with servers of other banks (such as when withdrawing money at a bank at which the user does not have an account). The ATMs provide a user interface and the servers provide services, such as checking on account balances and transferring money between accounts.
To provide access to servers not running on the same machine as the client, middleware is usually used. Middleware serves as the networking between the components of a client-server system; it must be run on both the client and the server. It provides everything required to get a request from a client to a server and to get the server's response back to the client. Middleware often facilitates communication between different types of computer systems. This communication provides cross-platform client-server computing and allows many types of clients to access the same data.
The server portion almost always holds the data, and the client is nearly always responsible for the user interface. The application logic, which determines how the data should be acted on, can be distributed between the client and the server (Fig. 2). The part of a system with a disproportionately large amount of application logic is termed “fat”; a “thin” portion of a system is a part with less responsibility delegated to it. Fat server systems, such as groupware systems and web servers, delegate more responsibility for the application logic to the server, whereas fat client systems, such as most database systems, place more responsibility on the client (Fig. 2). See also: Human-computer interaction
The canonical client-server model assumes two participants in the system. This is called a two-tiered system; the application logic must be in the client or the server, or shared between the two. It is also possible to have the application logic reside in a third layer separate from the user interface and the data, turning the system into a three-tier system. Complete separation is rare in actual systems; usually the bulk of the application logic is in the middle tier, but select portions of it are the responsibility of the client or the server.
The three-tier model is more flexible than the two-tier model because the separation of the application logic from the client and the server gives application logic processes a new level of autonomy. The processes become more robust since they can operate independently of the clients and servers. Furthermore, decoupling the application logic from the data allows data from multiple sources to be used in a single transaction without a breakdown in the client-server model. This advancement in client-server architecture is largely responsible for the notion of distributed data. See also: Distributed systems (computers)
Standard web applications are the most common examples of three-tier systems. The first tier is the user interface, provided via interpretation of Hyper Text Markup Language (HTML) by a web browser. The embedded components being displayed by the browser reside in the middle tier, and provide the application logic pertinent to the system. The final tier is the data from a web server. Quite often this is a database-style system, but it could be a data-warehousing or groupware system.
The desire to distribute servers across a network and have clients find them on demand has led to the development of component technologies. Components are the smallest self-managing, independent, and useful parts of a system that can work with other components to provide useful services. Each component provides an interface, which is a contract to do certain things asked of it. Therefore, systems can be quickly assembled by reusing existing components. For example, a program that needs to sort a list may ask a sorting component to do this so the programmer writing the new application need not write the sorting code. Components that provide the same interfaces can be interchanged for one another; for example, a user could purchase and install a faster sorting component, and programs using the old sorting component would automatically use the improved version.
The use of components requires additions to the traditional middleware package that can coordinate components and help components locate one another. The two primary middleware packages providing these services are the Common Object Request Broker Architecture (CORBA) and the Distributed Component Object Model (DCOM).
An industry-wide consortium created and advocates the standard known as CORBA. CORBA objects can exist anywhere on a network; their location is completely transparent (Fig. 3). Details such as an object's language or its operating system are also hidden from clients. Thus, the implementation of an object is of no concern to an invoking object; the interface is the only entity that a client needs to consider when selecting a serving object.
The most important part of a CORBA system is the object request broker (ORB). CORBA uses the object request broker to establish a client-server relationship between components. The object request broker intercepts service requests from the client objects and routes them to an appropriate server. CORBA uses an interface file written in an interface definition language (IDL) to specify the services that an object can provide, but programmers write code in their language of choice.
When clients request services, the requests are routed to the remote server using a local “stub” object and the object request broker. The stub relieves the application programmer from the burden of routing the message.
CORBA specifies two means by which an object can locate another object in a system. The first is the Naming Service. This service is analogous to the white pages in a phone book: An object looks up another object by the name under which the object registered itself with the object request broker when it was initialized. The second service is the Trading Service, which is like the yellow pages: Objects can ask the Trading Service which objects have registered with certain service characteristics. The trading repository then returns references to salient objects and gives the client information regarding the properties of the services. See also: Object-oriented programming
Like CORBA, DCOM separates interface from functionalty by using an interface definition language. The client-server contract is fulfilled by using object interfaces that make the implementation language and the location of objects transparent. When a DCOM client needs a server, it issues a request for an object supporting the required interface instantiated so that the interface becomes available.
Using interface pointers to mask stublike objects, DCOM supports transparent communication between clients and remote server objects. DCOM uses a model quite similar to the mechanism employed by CORBA to provide location-independent access to objects. Since DCOM provides access to interfaces only (and not objects), there is no means by which to locate specific objects.
Java is a programming language that allows programs to run on a variety of computing platforms without being modified; such a system is referred to as a mobile code system. Mobile code is distinguished from traditional application code in that it is dynamically executed by an application that provides the run-time environment. For code to be considered mobile, it must be portable, meaning the code can be run on a variety of platforms. Java uses bytecodes to provide portability and security. The bytecode system calls for programs to be “compiled” to the point where they can be run on a Java virtual machine, which translates the bytecodes into actual machine instructions in real time. Java virtual machines must adhere to a standard; this ensures that a Java program executes in the same manner on any machine. To provide security, the Java Verifier checks all code scheduled to be executed for malicious code.
Java's promise of “write once, run anywhere” makes it an appealing language in which to author pieces of a client-server system. Java also provides core classes that are a part of standard Java implementations. These core classes provide basic services that many programs require, and can decrease application development times by reducing the amount of code a programmer needs to write and debug.
When coupled with distributed object technology, Java forms a strong basis for the development of a robust system that supports client-server computing. A platform for universal network computing can be created by using Java as a programming language and mobile code system and CORBA or DCOM as an integration technology. Using DCOM or CORBA allows Java components to be split into client- and server-side components in many cases, providing the system with enhanced flexibility in distributing web-based applications. See also: Digital computer; Programming languages