Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



How to implement a server interface with subsessions

A server side subsession is represented by an instance of a class derived from CObject.

The following sections refer to an example server, known as the count server. The code fragments are taken from the example that can be found at ...\examples\Base\IPC\ClientServer\complex.

In the example, a server side session is represented by the CSession2 derived class CCountSession. The server session can have any number of subsessions, referred to as counters in the example. The subsessions are instances of the CCountSubSession class and these are derived from CObject.

Unlike the implementation for a simple server interface, as shown in the example that can be found at ...\examples\Base\IPC\ClientServer\simple, the functions to service client requests, e.g. Increase(), are in class CCountSubSession rather than CCountSession.

The important points to note are:


Server session representation

The CCountSession class is defined as:

class CCountSession : public CSession2
    {
public:
      // Create the session
    static CCountSession* NewL();
    
public:
      // Constructor
    CCountSession();
    
      // Called by client/server framework after 
      // session has been successfully created
    void CreateL(); 
        
      // Service request
    void ServiceL(const RMessage2& aMessage);
    void DispatchMessageL(const RMessage2& aMessage);

      // Creates new subsession
    void NewCounterL(const RMessage2& aMessage);  
      
      // Closes the session
    void CloseSession();
    
      // Gets the number of resources (i.e. CCountSubSession objects)
    void NumResources(const RMessage2& aMessage);
    
      // Utility to return the CCountSubSession (subsession) object
    CCountSubSession* CounterFromHandle(const RMessage2& aMessage,TInt aHandle);    

      // Delete the subsession object through its handle.
    void DeleteCounter(TInt aHandle);
      
      // Gets the number of server-side subsession objects.
    TInt CountResources();
      
      // Panics client
    void PanicClient(const RMessage2& aMessage,TInt aPanic) const;

private:
      // Object container for this session.
    CObjectCon *iContainer;

      // Object index which stores objects
      // (CCountSubSession instances) for this session.
    CObjectIx* iCountersObjectIndex;

      // Total number of resources. In this example
      // a resource is just the number of CCountSubSession objects.
    TInt iResourceCount;
    };


Notes

[Top]


Subsession object representation

The CCountSubSession class which represents the subsession is defined as:

class CCountSubSession : public CObject
    {
public:
      // creates a new CCountSubSession object.
    static CCountSubSession* NewL(CCountSession* aSession);
    
public: 
    CCountSubSession(CCountSession* aSession); 
    void ConstructL(CCountSession* aSession);
    void SetFromStringL(const RMessage2& aMessage);
    void Increase();
    void IncreaseBy(const RMessage2& aMessage);
    void Decrease();
    void DecreaseBy(const RMessage2& aMessage);
    void Reset();
    void CounterValue(const RMessage2& aMessage);
   
protected:
      // The session that owns this CCountSubSession object.
    CCountSession* iSession;
    
private:
      // The counter value
    TInt iCount;
    };


Notes

[Top]


Implementing a subsession request

Subsession requests are handled in a similar way to session requests.

A subsession request is initially handled by the associated session, i.e. it is passed to the appropriate CSession2::ServiceL().

void CCountSession::ServiceL(const RMessage2& aMessage)
    {
    TRAPD(err,DispatchMessageL(aMessage));
    aMessage.Complete(err);
    }

The appropriate service function is called via DispatchMessageL() and the asynchronous request is completed with aMessage.Complete(). This applies to messages targeted at sessions and subsessions.


DispatchMessageL()

The following code fragment shows important parts of this function:

void CCountSession::DispatchMessageL(const RMessage2& aMessage)
    {
        // First check for session-relative requests
    switch (aMessage.Function())
        {
    case ECountServCreateSubSession:// Request to create a subsession
        NewCounterL(aMessage);
        return;
    case ECountServCloseSession:    // Request to delete a subsession
        CloseSession();
        return;
        ...
        }
    ...
 
                             // Must be a subsession request
                             // Find out Which subsession and
                             // forward the request to it.
    CCountSubSession* counter=CounterFromHandle(aMessage,aMessage.Int3())
    switch (aMessage.Function())
        {
        ...
    case ECountServValue:
        counter->CounterValue(aMessage);
        return;
    default:
        PanicClient(EBadRequest);
        return;
        }
    }

CCountSubSession* CCountSession::CounterFromHandle(const RMessage2& aMessage,TInt aHandle)
    {
    CCountSubSession* counter = (CCountSubSession*)iCountersObjectIndex->At(aHandle);
    if (counter == NULL)
        {
        PanicClient(aMessage, EBadSubsessionHandle); 
        }
    return counter;
    }

Notes