Chat Demo - C++ Clients

The chat demo includes two simple command-line clients written in C++. The first client uses the push model and demonstrates how to implement an Ice object to receive callbacks from the chat server, and how to create and maintain a Glacier2 session. The second client (not shown here) uses the pull model. The code snippets below were adapted from the push client to give you a peek into an Ice for C++ program; if you want to see the entire source code for either of the clients, we encourage you to download the source archive for the chat application.

Push Client

One of the first tasks of any Ice program is to create an instance of the Ice run time, represented by the C++ class Ice::Communicator. Having done that, the push client's next job is to establish a session with the Glacier2 router. It begins by obtaining a proxy for the communicator's default router and down-casting it to a proxy for the derived interface Glacier2::Router. This is done using a checked cast, which behind the scenes sends a request to the target object to confirm that it implements the desired interface:

Ice::CommunicatorPtr communicator = ...
Ice::RouterPrx defaultRouter = communicator->getDefaultRouter();
Glacier2::RouterPrx router = Glacier2::RouterPrx::checkedCast(defaultRouter);

With the router's proxy in hand, the client can create a Glacier2 session. The createSession operation returns a proxy of type Glacier2::Session, and the client narrows this proxy to the derived interface Chat::ChatSession that we saw earlier. In this case, the client uses an uncheckedCast; this avoids sending a confirmation request to the target object and is useful when the client already knows the target object implements the desired interface:

Glacier2::SessionPrx s = router->createSession("user", "password");
Chat::ChatSessionPrx session = Chat::ChatSessionPrx::uncheckedCast(s);

After successfully creating the session, the client must take care of a little house-keeping before it can instantiate its callback object. The first step is to create an object adapter, which is the Ice construct responsible for dispatching incoming requests to Ice objects. Activating the object adapter allows the Ice run time to begin dispatching requests:

Ice::ObjectAdapterPtr adapter =
    communicator->createObjectAdapterWithRouter("Chat.Client", router);
adapter->activate();

Every Ice object requires a unique identity, which is a structure consisting of two strings representing a name and a category. When using callbacks with Glacier2, the client must use a category supplied by Glacier2. The code below prepares the identity for the callback object:

Ice::Identity callbackReceiverIdent;
callbackReceiverIdent.name = "callbackReceiver";
callbackReceiverIdent.category = router->getCategoryForClient();

Now the client can instantiate its callback object. Since the client activated the object adapter earlier, it is possible for requests to be dispatched to this object as soon as we add it to the object adapter. In turn, the object adapter returns a proxy that we can down-cast to the appropriate interface:

Ice::ObjectPtr obj = new ChatRoomCallbackI;
Ice::ObjectPrx proxy = adapter->add(obj, callbackReceiverIdent);
Chat::ChatRoomCallbackPrx callback =
    Chat::ChatRoomCallbackPrx::uncheckedCast(proxy);

The last step is to join the chat room, which we accomplish by invoking setCallback on the session:

session->setCallback(callback);

The client contains some additional code that we do not show here. For example, the client must ensure that its Glacier2 session does not expire, which it does by "pinging" the session at regular intervals. Lastly, this client must also prompt the user to enter chat messages until the user elects to quit the program.

Previous: Slice Interfaces Next: Graphical Clients

Terms of Use | Privacy © 2010 ZeroC, Inc.