# Chat using CORBA

## Overview

This is a simple chat application that demonstrates the use of callbacks in CORBA.

The server provides a single CORBA Chat Server object that maintains a group of chat rooms. Clients may retrieve a list of rooms, join a room or ask the Chat Server to create a new room. Each room is represented by a CORBA object which is implemented by the server.

Once connected to a Chat Server, the client allows the user to join a chat room and send messages to all other users in the same room. The client also displays messages sent by other users in the same room.

## Building

### Building the Client

In the Functional Developer Environment, open the CORBA Chat client example from the Open Example Dialog. Choose Project->Build from the project's window to compile and link the project.

### Building the Server

In the Functional Developer Environment, open the CORBA Chat server example from the Open Example Dialog. Choose Project->Build from the project's window to compile and link the project.

### Running the Server and Client

Since the Chat demo uses callbacks in CORBA, the client-server relationship is blurred. The Chat client serves requests sent to it by the Chat server and so must listen on a port number. The Functional Developer ORB has a default port number for servers so if both programs are run on the same machine they will clash unless one of the programs is switched to listen on a different port.

If you run the programs from within the Functional Developer Environment then the project settings for the Chat client will automatically set a different port number for the client (see the Debug tab of the Project/Settings dialog). However, when running standalone you must do this manually using the -ORBport command line argument:

      chat-client -ORBport 3673

If you want to run multiple Chat clients in addition to the server then you must assign a different port number for each client.

### Using the Server and Client

The server's window is split into two parts. The top half lists all the rooms the server maintains, along with the number of users in each room. The bottom half is a log of events and messages. Initially, there are no rooms on the server. To create a room click the Create Room button or select Room->Create... from the menu bar and type in the name of the new room. The room name will appear in the top half of the server's window.

In order to join the chat room you will need to connect the client to the server. Select the Connect button in the client's toolbar or choose Server->Connect... from the client's menu bar. The client will prompt you to locate a file. This file should contain the string version of the reference to the Chat Server object. The Chat server writes the reference for it's Chat Server object to the file c:\temp\chat.ior during initialization. By default the client's file locator dialog points to this file so just click the Open button. When running the client and server on separate machines, you may need to copy the chat.ior file from the server's machine to the client's machine or you may be able to access it from the client's machine across a network connection. In either case you should use the dialog to locate the file before clicking Open.

Now that the client is connected to the server the rooms available on the server should appear in the top-left of the client's window. Selecting a room causes a list of all the users in the room to be displayed in the top-right of the window. To join a room select the room name and press the Join Room button or choose Server->Join Room from the menu. The status bar will be updated to indicated which room you have joined. You may send a message to the room by typing in the field at the very bottom of the client window. Pressing Return sends the message. All messages sent to a room are listed in the list box in the middle of the client's window. The user name that other clients and the server know you by is displayed in the status bar. To change the user name select the Change name button in the client's toolbar and type the new name when prompted.

## Implementation Overview

### IDL

The IDL source defines three interfaces; `ChatRoom`, `ChatServer` and `ChatClientCallback`. These are described in the following sections.

#### ChatServer

The `ChatServer` interface describes a CORBA object implemented by the Chat server. It is used to manage a group of `ChatRoom` objects. There is only one `ChatServer` object in the server. It has a read-only attribute that contains the sequence of objects it manages and a factory operation for creating a new `ChatRoom` object.

#### ChatRoom

The `ChatRoom` interface describes CORBA objects which represent chat rooms. There is one object for each chat room and they are implemented by the Chat server. The interface has read-only attributes for the chat room name and the users that are currently in the chat room. There are operations that clients can use to send a message to the chat room (which the room forwards to all its users), and to join or leave the room.

#### ChatClientCallback

The `ChatClientCallback` interface describes a CORBA callback object that is implemented by the Chat client. It includes operations which are invoked by the server to notify the client of certain events e.g. a message being sent to a room, or a user joining or leaving a room. The interface also has a read-only attribute that contains the user name for the client. This attribute is read by other Chat clients as well as the server.

### Chat Client

The Chat client can be split into three parts; the Chat Client API, the callback server and the user interface. The Chat Client API implements the logic of the client. It hides the details of using CORBA from the user interface and callback server by defining an abstract layer of types and functions. Thus, if the CORBA interface changes, only the Chat Client API implementation needs to be changed. Alternatively, the Chat Client API could be re-implemented to reduce the number of CORBA requests that is makes by caching the results of previous requests and information it receives from the callback server (e.g. room and user names). Again such changes would be hidden from the rest of the application.

The implementation is split into four modules:

chat-client
  Defines the Chat Client API. See the file chat-client.dylan
chat-client-implementation
  Implementation of the Chat Client API. See the file chat-client.dylan
chat-client-callback
  Implementation of the `ChatClientCallback` interface. See the file callback.dylan
chat-client-gui
  Implementation of the `DUIM` user interface for the chat client. See the file frame.dylan

### Chat Server

Like the client, the Chat server can be split into three parts; the Chat Server API, the CORBA server implementation and the user interface. However, the Chat Server API is not as independent as the Chat Client API. The CORBA server implementation relies on the Chat Server API just like the callback server in the client relies on the Chat Client API. However, the Chat Server API also relies on the CORBA server implementation. In particular it needs the server when creating `ChatServer` and `ChatRoom` objects.

The implementation is split into five modules:

chat-server
  Defines the Chat Server API. See the file chat-server.dylan
chat-server-implementation
  Implementation of the Chat Server API. See the file chat-server.dylan
corba-server
  Defines the interface needed by the Chat Server API to create `ChatServer` and `ChatRoom` objects.
corba-server-implementation
  Implementation of the `ChatServer` and `ChatRoom` interfaces. See the file corba-server.dylan
chat-server-gui
  Implementation of the `DUIM` user interface for the chat server. See the file frame.dylan