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 use 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.
Using a Glacier2 router requires a fair amount of boilerplate code that is often duplicated in each program. To simplify the creation of Glacier2 command-line applications and minimize this code duplication, Ice includes the
Glacier2::Application helper class. Our C++ client subclasses
Glacier2::Application and overrides two pure virtual functions:
createSession method is responsible for creating a new Glacier2 session. Our implementation prompts for a user name and password and then invokes
createSession on the router proxy:
This code is making use of the router convenience method, which returns a router proxy that is obtained from the program's configuration properties.
createSession completes successfully, the base class invokes
runWithSession to execute the program's main loop. Our implementation of
runWithSession starts by down-casting the session proxy:
session convenience method returns the proxy for the session that we created in
createSession. Since this is a proxy of type
Glacier2::Session, we narrow it to the derived interface
Chat::ChatSession that we saw earlier. We use
uncheckedCast here to avoid sending a confirmation request to the target object because the client already knows that the target object implements the desired interface.
Now we can invoke the
setCallback operation on the
ChatSession interface to join the chat room:
There's a lot happening in this short snippet of code. First, we instantiate our callback servant class
ChatRoomCallbackI and pass it to the
addWithUUID convenience function. This function registers our servant with an object adapter intended especially for callback objects, creating that object adapter if it doesn't already exist.
addWithUUID also ensures that the object identity associated with the servant includes a UUID and complies with Glacier2's conventions for callback objects. We narrow the resulting callback proxy to the type
Chat::ChatRoomCallback using another unchecked cast, and finally pass this proxy to the
From now on, any events that occur in the chat room will be relayed to our callback servant, which prints an appropriate message to the console. Our main loop simply prompts for new chat messages until the user elects to quit:
Glacier2::Application class takes care of mundane details such as keeping the session alive, recovering from errors, and automatically restarting the session when possible.