Symbian3/SDK/Source/GUID-FAE3F35C-04C1-5CF4-8090-9DF58AD1C02A.dita
changeset 0 89d6a7a84779
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-FAE3F35C-04C1-5CF4-8090-9DF58AD1C02A.dita	Thu Jan 21 18:18:20 2010 +0000
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-FAE3F35C-04C1-5CF4-8090-9DF58AD1C02A" xml:lang="en"><title>How
+to implement a server interface with subsessions</title><shortdesc>Provides code snippets to help you to implement a server interface
+with subsessions.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>A server side subsession is represented by an instance of a class derived
+from <codeph>CObject</codeph>. </p>
+<p>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 <filepath>...\examples\Base\IPC\ClientServer\complex</filepath>. </p>
+<p>In the example, a server side session is represented by the <codeph>CSession2</codeph> derived
+class <codeph>CCountSession</codeph>. The server session can have any number
+of subsessions, referred to as counters in the example. The subsessions are
+instances of the <codeph>CCountSubSession</codeph> class and these are derived
+from <codeph>CObject</codeph>. </p>
+<p>Unlike the implementation for a simple server interface, as shown in the
+example that can be found at <filepath>...\examples\Base\IPC\ClientServer\simple</filepath>,
+the functions to service client requests, e.g. <codeph>Increase()</codeph>,
+are in class <codeph>CCountSubSession</codeph> rather than <codeph>CCountSession</codeph>. </p>
+<p>The important points to note are: </p>
+<ul>
+<li id="GUID-98D487B0-ECFF-5A83-BEF0-C66475836888"><p>the <codeph>CCountSession</codeph> class
+contains the object container for all the subsession objects which belong
+to this session. </p> </li>
+<li id="GUID-BCE1BF57-FC9E-58CF-9E77-1AD48632DFC0"><p>the <codeph>CCountServer</codeph> class
+contains the <i>one and only</i> object container index through which all
+object containers within the server are produced. </p> </li>
+<li id="GUID-78880ABD-904A-5D3C-988A-646CE2998050"><p>the <codeph>CCountSession</codeph> class
+contains an object index through which a handle number can be generated for
+the subsession. </p> </li>
+</ul>
+<section id="GUID-D49A6975-81B7-4BEE-8F46-C0F850CB4974"><title>Server session representation</title> <p>The <codeph>CCountSession</codeph> class
+is defined as: </p> <codeblock id="GUID-F8FED60B-823A-5965-97F2-0BF6EC24620D" xml:space="preserve">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&amp; aMessage);
+    void DispatchMessageL(const RMessage2&amp; aMessage);
+
+      // Creates new subsession
+    void NewCounterL(const RMessage2&amp; aMessage);  
+      
+      // Closes the session
+    void CloseSession();
+    
+      // Gets the number of resources (i.e. CCountSubSession objects)
+    void NumResources(const RMessage2&amp; aMessage);
+    
+      // Utility to return the CCountSubSession (subsession) object
+    CCountSubSession* CounterFromHandle(const RMessage2&amp; 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&amp; 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;
+    };
+</codeblock> <p><b>Notes</b> </p> <ul>
+<li id="GUID-DD9D1AE3-315E-5ADF-A251-5F9BAAF24EED"><p>The data member <codeph>iCountersObjectIndex</codeph> is
+a pointer to an <i>object index</i>. Once a subsession object has been created
+and stored in its <i>object container</i>, it is then added to the <i>object
+index</i> to generate a unique handle number for the counter (<keyword>subsession
+object</keyword>). </p> </li>
+<li id="GUID-0AE88EE6-1E87-5699-92FF-F55225320DF8"><p>The <codeph>CCounterFromHandle()</codeph> function
+returns the subsession object corresponding to a specified handle number. </p> </li>
+<li id="GUID-64A79B53-B798-50DA-B4F5-0DA5881F964E"><p>The <codeph>NewCounterL()</codeph> function
+creates a new subsession object. </p> </li>
+<li id="GUID-C9C9619D-EE0D-5B3F-B51C-354C9D7066D1"><p>The <codeph>DeleteCounter()</codeph> function
+deletes a subsession object. This is called when the client program requests
+to close a subsession. </p> </li>
+</ul> </section>
+<section id="GUID-CB7E6555-DE45-426A-B816-3736E72904FE"><title>Subsession object representation</title> <p>The <codeph>CCountSubSession</codeph> class
+which represents the subsession is defined as: </p> <codeblock id="GUID-A91DD957-4A51-58E1-B0A0-843DAF9FF483" xml:space="preserve">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&amp; aMessage);
+    void Increase();
+    void IncreaseBy(const RMessage2&amp; aMessage);
+    void Decrease();
+    void DecreaseBy(const RMessage2&amp; aMessage);
+    void Reset();
+    void CounterValue(const RMessage2&amp; aMessage);
+   
+protected:
+      // The session that owns this CCountSubSession object.
+    CCountSession* iSession;
+    
+private:
+      // The counter value
+    TInt iCount;
+    };</codeblock> <p><b>Notes</b> </p> <ul>
+<li id="GUID-04B1ACC9-AA68-56C7-B42A-DC7DAA0749B0"><p>The <codeph>NewL()</codeph> function
+creates and returns a new instance of the subsession object. This is called
+when the client requests the creation of a new subsession. </p> </li>
+<li id="GUID-8BF98800-E081-5120-914F-60AE09C1A70A"><p>The <i>message service
+functions</i> <codeph>Increase()</codeph>, <codeph>IncreaseBy()</codeph> etc.
+respond appropriately to client requests. </p> </li>
+</ul> </section>
+<section id="GUID-1031D378-90C7-42A4-B1E5-C8BA10145B86"><title>Implementing a subsession request</title> <p>Subsession requests
+are handled in a similar way to session requests. </p> <p>A subsession request
+is initially handled by the associated session, i.e. it is passed to the appropriate <codeph>CSession2::ServiceL()</codeph>. </p> <codeblock id="GUID-AE6EDE6F-54B2-56DC-A793-A6AE630A223A" xml:space="preserve">void CCountSession::ServiceL(const RMessage2&amp; aMessage)
+    {
+    TRAPD(err,DispatchMessageL(aMessage));
+    aMessage.Complete(err);
+    }
+</codeblock> <p>The appropriate service function is called via <codeph>DispatchMessageL()</codeph> and
+the asynchronous request is completed with <codeph>aMessage.Complete()</codeph>.
+This applies to messages targeted at sessions and subsessions. </p> <p><b>DispatchMessageL()</b> </p> <p>The following code fragment shows important parts of this function: </p> <codeblock id="GUID-EB719B38-AA2C-5C19-B7BE-2332BD853057" xml:space="preserve">void CCountSession::DispatchMessageL(const RMessage2&amp; 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-&gt;CounterValue(aMessage);
+        return;
+    default:
+        PanicClient(EBadRequest);
+        return;
+        }
+    }</codeblock> <codeblock id="GUID-F0C7D2A2-FC3E-5CC0-A776-7D7B7047D758" xml:space="preserve">CCountSubSession* CCountSession::CounterFromHandle(const RMessage2&amp; aMessage,TInt aHandle)
+    {
+    CCountSubSession* counter = (CCountSubSession*)iCountersObjectIndex-&gt;At(aHandle);
+    if (counter == NULL)
+        {
+        PanicClient(aMessage, EBadSubsessionHandle); 
+        }
+    return counter;
+    }
+</codeblock> <p><b>Notes</b> </p> <ul>
+<li id="GUID-55B94E1E-C761-5D39-9EBF-9A2E600E26A3"><p>The function first checks
+for messages which are specific to a session and this includes those requests
+to create and delete a subsession. </p> </li>
+<li id="GUID-D65039AA-E45E-5CA6-8A25-E8F3680CDA72"><p>After deciding that
+messages must be forwarded to a subsession, the function uses the handle number
+supplied through the fourth parameter in the message argument array and the <codeph>CounterFromHandle()</codeph> function
+to retrieve the appropriate subsession object. </p> </li>
+<li id="GUID-54BC7669-BBA9-5134-857A-8F4060059EB7"><p>It then invokes the
+appropriate message service function on that subsession to deal with the client
+request. </p> </li>
+<li id="GUID-7CA3D0C0-E7DB-58FC-A89D-2584C25A7685"><p>The <codeph>At()</codeph> function
+is provided by the <codeph>CObject</codeph> base class. </p> </li>
+</ul> </section>
+</conbody></concept>
\ No newline at end of file