Slice Interfaces

Slice is the interface definition language used by Ice. With it, you can define the client–server contract for your application, including all of the interfaces, operations, parameters, data types, and exceptions. If you are familiar with programming languages such as C++, Java, or C#, the Slice syntax will be immediately recognizable.

The sections below present the Slice interfaces for the push and pull models. If you are only interested in learning about Ice for a particular programming language, you should review the push model for C++, JavaScript, Java, or C#, and the pull model for PHP.

Push Model

A push client must implement the following interface:

module Chat
{
    interface ChatRoomCallback
    {
        void init(Ice::StringSeq users);
        void send(long timestamp, string name, string message);
        void join(long timestamp, string name);
        void leave(long timestamp, string name);
    }
}

The server invokes the init operation when the client joins the chat room; the operation supplies a list of the users in the room as a string sequence. The server calls the send operation to notify the client about a new message, including a time stamp and the name of the sender. Finally, the server calls the join and leave operations when a user joins or leaves the chat room, respectively.

Glacier2 provides a session facility that we can extend for our push model. The server-side Slice interface derives from the Glacier2::Session interface:

module Chat
{
    interface ChatSession extends Glacier2::Session 
    {
        void setCallback(ChatRoomCallback* cb);
        long send(string message) throws InvalidMessageException;
    }
}

A client joins the chat room by establishing a session and calling setCallback to pass the proxy for its callback object. The client uses send to send a new message to all users currently in the chat room. Lastly, before it terminates, the client invokes destroy (inherited from Glacier2::Session) to leave the room and destroy its session.

Pull Model

Our pull model uses Slice classes to define events that occur in the chat room. ChatRoomEvent is the base class for all events and contains a time stamp and a user name. Subclasses of ChatRoomEvent correspond to a user joining the room, leaving the room, and sending a message. To determine which type of event has occurred, a client must perform a language-specific down-cast.

module PollingChat 
{
    class ChatRoomEvent
    {
        long timestamp;
        string name;
    }
    sequence<ChatRoomEvent> ChatRoomEventSeq;
    class UserJoinedEvent extends ChatRoomEvent {}
    class UserLeftEvent extends ChatRoomEvent {}
    class MessageEvent extends ChatRoomEvent
    {
        string message;
    }
}

We do not use Glacier2 for the pull model, therefore we need to create our own session facility:

module PollingChat
{
    interface PollingChatSession
    {
        Ice::StringSeq getInitialUsers();
        ChatRoomEventSeq getUpdates();
        long send(string message) throws Chat::InvalidMessageException;
        void destroy();
    }
    interface PollingChatSessionFactory
    {
        PollingChatSession* create(string name, string password)
            throws CannotCreateSessionException;
    }
}

A pull client creates a session by invoking create on the factory. This operation accepts a user name and password (our implementation accepts any combination) and returns a proxy to the session object. Having created a session, the client invokes getInitialUsers to obtain the list of users currently in the chat room, then periodically invokes getUpdates to receive events. The send operation allows the client to post a new message, and destroy terminates the client's session.