# examples/S60CppExamples/ClientServerSync/doc/index.html

    00001 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    00002 <html>
    00003
    00004 <head>
    00005 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
    00006 <title>Synchronous Client/Server Example</title>
    00007 <link href="style.css" rel="stylesheet" type="text/css">
    00008 </head>
    00009
    00010 <table border="0" width="100%" height="8" bgcolor="#eeeeee">
    00011 <tr> <td width="100%" height="1"><b><font size="2" color="#000000" face="Arial, Helvetica, sans-serif"><strong><a name=Top></a>
    00012 S60 5th Edition SDK </strong></font></b><br><i>Example Applications Guide</i></td></tr> </table>
    00013 <!-- Generated by Doxygen 1.4.5 -->
    00014 <div class="tabs">
    00015   <ul>
    00016     <li id="current"><a href="index.html"><span>Main&nbsp;Page</span></a></li>
    00017     <li><a href="annotated.html"><span>Classes</span></a></li>
    00018     <li><a href="files.html"><span>Files</span></a></li>
    00019   </ul></div>
    00020 <h1>Synchronous Client/Server Example</h1>
    00021 <p>
    00022 <a class="el" href="index.html#Intro_sec">1. About this Example</a> <br>
    00023 <a class="el" href="index.html#Arch_sec">2. Architecture</a> <br>
    00024 <a class="el" href="index.html#Design_sec">3. Design and Implementation</a><p>
    00025 <hr>
    00026 <h2><a class="anchor" name="Intro_sec">
    00027 1. About this Example</a></h2>
    00028 This example demonstrates the architecture of a simple client server application utilising synchronous calls to the server. The server supplies the current time to its clients.<p>
    00029 <hr>
    00030 <h3><a class="anchor" name="Sub11">
    00031 1.1 APIs demonstrated</a></h3>
    00032 <ul>
    00033 <li>CServer2</li><li>CSession2</li><li>RMessagePtr2</li><li>RMessage2</li><li>RSessionBase</li></ul>
    00034 <p>
    00035 <hr>
    00036 <h3><a class="anchor" name="Sub12">
    00037 1.2 Prerequisites</a></h3>
    00038 This example exists as a complete application, and has the standard Symbian OS application architecture employing the Application, Document, UI, and View classes. The example makes use of several other Symbian OS concepts which the reader should be aware of before attempting to understand this example. These are:<p>
    00039 <ul>
    00040 <li>Inter process communication, in particular the following topics:<ul>
    00041 <li>Inter-process communication overview.</li><li>Client/server overview.</li><li>Using client/server.</li></ul>
    00042 </li></ul>
    00043 <p>
    00044 <ul>
    00045 <li>Thread and process management, in particular the following topics:<ul>
    00046 <li>Thread and process management overview.</li><li>Semaphores overview.</li><li>Threads and processes overview.</li><li>Using semaphores.</li></ul>
    00047 </li></ul>
    00048 <p>
    00049 <hr>
    00050 <h3><a class="anchor" name="Sub13">
    00051 1.3 Running this example</a></h3>
    00052 The application initially presents a default time to the user, as shown in the following screenshot.<p>
    00053 <div align="center">
    00054 <img src="initial_screen.jpg" alt="initial_screen.jpg">
    00055 </div>
    00056 <p>
    00057 The Options menu presents the following choices:<p>
    00058 <div align="center">
    00059 <img src="options_menu.jpg" alt="options_menu.jpg">
    00060 </div>
    00061 <p>
    00062 <ul>
    00063 <li>Select <b>Display Time</b> to request a time update from the server.</li><li>Select <b>Exit</b> to exit the application.</li></ul>
    00064 <p>
    00065 On selecting <b>Display Time</b>, the display will be updated, to reflect the server supplied time, as shown in the following screenshot.<p>
    00066 <div align="center">
    00067 <img src="updated_time.jpg" alt="updated_time.jpg">
    00068 </div>
    00069 <p>
    00070 <hr>
    00071 <h2><a class="anchor" name="Arch_sec">
    00072 2. Architecture</a></h2>
    00073 This example exists as a complete application and has the standard Symbian OS application architecture employing the Application, Document, UI, and View classes. The reader should be familiar with this architecture before proceeding.<p>
    00074 <hr>
    00075 <h2><a class="anchor" name="Design_sec">
    00076 3. Design and Implementation</a></h2>
    00077 The following component diagram illustrates the split of classes over the Client and Server components, and their inter-relationships.<p>
    00078 <div align="center">
    00079 <img src="client-server_components.jpg" alt="client-server_components.jpg">
    00080 </div>
    00081 <p>
    00082 The client is a standard Symbian OS application, utilising an RSessionBase-derived object to communicate with the server. The server is implemented as an EXE.<p>
    00083 In the following description, an overview of this example's design is presented in the Design Overview section. This is followed by a description of two use case scenarios, where the user:<ul>
    00084 <li>Invokes the application - here, the application establishes communication with the server, creating the server if necessary. This is achieved using the <a class="el" href="class_r_time_server_session.html">RTimeServerSession</a> class, and is described in the Creating a session section.</li><li>Makes a server request - the application uses the established session to request data from the server. This is described in the Making a server request section.</li></ul>
    00085 <p>
    00086 <hr>
    00087 <h3><a class="anchor" name="Sub31">
    00088 3.1 Design overview</a></h3>
    00089 The Symbian OS client/server architecture uses four key concepts: server (CServer2), session (CSession2 and RSessionBase), sub-session (RSubSessionBase), and message (RMessage2, and RMessagePtr2).<p>
    00090 Servers derive from CServer2, and are responsible for handling any requests from clients to establish connections.<p>
    00091 The session represents the channel of communication between client and server. Clients use a derivation of RSessionBase, and servers use a derivation from CSession2.<p>
    00092 The following class diagram shows the server-session associations for this example.<p>
    00093 <div align="center">
    00094 <img src="server-session_classes.png" alt="server-session_classes.png">
    00095 </div>
    00096 <p>
    00097 A client can create multiple sessions with a server. It is more resource-efficient to use sub-sessions, but this feature is not employed in this example, for simplicity.<p>
    00098 The RMessage2 class is the data structure passed between client and server. The client does not manipulate this directly; they use a TIpcArgs object to package the message information that is to be sent to the server. Server side sessions read from, and write to, this structure to receive and send data.<p>
    00099 <hr>
    00100 <h3><a class="anchor" name="Sub32">
    00101 3.2 Creating a session</a></h3>
    00102 To create a session, the client must establish a channel of communication with the server. The following diagram shows the sequence involved.<p>
    00103 <div align="center">
    00104 <img src="session_sequence_diagram.png" alt="session_sequence_diagram.png">
    00105 </div>
    00106 <p>
    00107 <ol type=1>
    00108 <li>Connect is called on construction of the document. This function is responsible for starting the server, if necessary, and establishing communication with the server.</li><li>It is necessary to start the server if it is not already running. StartServer accomplishes this, and returns an appropriate error code on completion. This is described further in the Starting the server section.</li><li>If the server was started successfully (or was already running), a session is created by calling the inherited CreateSession function. This takes three parameters. These are:<ul>
    00109 <li>Server name - this is used to search for an already existing server.</li><li>Version - the lowest version of the server with which this client is compatible.</li><li>Message slots - the number of asynchronous message requests that the client can have outstanding at any time. For a synchronous server, this is zero.</li></ul>
    00110 </li><li>The CreateSession function calls corresponding function from kernel side. The actual name of this function is undocumented.</li><li>The kernel layer calls the server's NewSessionL function. The exact mechanism is not documented but is included to show the complete sequence of events. NewSessionL verifies the client version, returning an error if it is not compatible with the server. It then creates a new <a class="el" href="class_c_time_server_session.html">CTimeServerSession</a> to handle the client/server communication.</li><li>The session is created using the standard Symbian OS two-phase construction.</li><li>The new session is registered with the server, using IncrementSessions. The server keeps a count of the number of open sessions. The DecrementSessions function is called when a server session is destroyed, and terminates the server when there are no more open sessions.</li></ol>
    00111 <p>
    00112 <hr>
    00113 <h3><a class="anchor" name="Sub321">
    00114 3.2.1 Starting the server</a></h3>
    00115 A server needs its own thread of execution. In this example, the client uses StartServer to check whether the server is running. If the server is not running, a thread is created and the server is started.<p>
    00116 The following diagram shows the sequence involved in creating the server.<p>
    00117 <div align="center">
    00118 <img src="start_server_sequence.png" alt="start_server_sequence.png">
    00119 </div>
    00120 <p>
    00121 <ol type=1>
    00122 <li>The StartServer function attempts to find an already running server. If it cannot, it will create a new server, waiting until the server has been created before returning.</li><li>A new TFindServer object is created with the server name to search for.</li><li>The call to TFindServer::Next returns KErrNone if the server was found.</li><li>A new RSemaphore is created.</li><li>The call to RSemaphore::CreateGlobal is passed the semaphore name to use. The semaphore needs to be global since the client and server run in separate processes (on the target). The server uses this semaphore to tell the client when the server construction is complete.</li><li>CreateServerProcess will create and run the server. This is described in the Creating a process for the server.</li><li>The client now waits for the server to initialise and become ready to accept requests. It accomplishes this by calling RSemaphore::Wait.</li><li>When the server issues a corresponding RSemaphore::Signal, the client will continue. The semaphore is now closed using RSemaphore::Close.</li></ol>
    00123 <p>
    00124 <hr>
    00125 <h3><a class="anchor" name="Sub322">
    00126 3.2.2 Creating a process for the server</a></h3>
    00127 The sequence involved in creating a process for the server is shown below. On emulator it creates a thread, because server must run as a thread in the emulator's process, and a process in target device.<p>
    00128 <div align="center">
    00129 <img src="server_process_creating.png" alt="server_process_creating.png">
    00130 </div>
    00131 <p>
    00132 <ol type=1>
    00133 <li>The CreateServerProcess function is responsible for creating a process for the server to run in, then starting the server.</li><li>A handle for manipulating the server is created using RProcess::Create.</li><li>The RProcess::Create is supplied with three parameters. These are:<ul>
    00134 <li>Server file name - the name of the server, including the path, to be executed.</li><li>Parameters - any data to be passed to the server (in this case, no data is passed).</li><li>UID - the UID of the server executable.</li></ul>
    00135 </li><li>The process has now been created by the kernel. The process is suspended until a call to RProcess::Resume is made.</li><li>The process is signalled to start by calling RProcess::Resume.</li><li>Kernel's DProcess::Resume() is called.</li><li>The E32Main is called, which is the EXE entry point.</li><li>The E32Main call starts processing at the <a class="el" href="class_c_time_server.html#d575a6cfda27d2fc60179c9cf5f90663">CTimeServer::ThreadFunction</a>. This is described in the Server-side initialisation section.</li><li>The handle to the server is no longer required, and is closed. Close must be called here, otherwise this process would have an open reference to the server's process. This would prevent the process being released after the server terminates.</li></ol>
    00136 <p>
    00137 <hr>
    00138 <h3><a class="anchor" name="Sub323">
    00139 3.2.3 Server-side initialisation</a></h3>
    00140 An EXE component implements the E32Main function, which provides the API for the operating system to start the executable. This function returns the address of the ThreadFunction function to be called.<p>
    00141 The following diagram shows the initialisation the server undergoes on startup.<p>
    00142 <div align="center">
    00143 <img src="server_startup.png" alt="server_startup.png">
    00144 </div>
    00145 <p>
    00146 <ol type=1>
    00147 <li>Kernel calls EXE entrypoint E32Main().</li><li><a class="el" href="class_c_time_server.html#d575a6cfda27d2fc60179c9cf5f90663">CTimeServer::ThreadFunction</a> is responsible for setting up any services that this thread/process requires, as well as creating an instance of the <a class="el" href="class_c_time_server.html">CTimeServer</a> class to service requests from clients. It is important to note that ThreadFunction cannot leave. Any errors that occur need to be handled or must raise a panic, as there is no way to pass error information back to the calling thread.</li><li>A cleanup stack is constructed and initialised. A thread/process does not have a cleanup stack by default, so one has to be created for it.</li><li><a class="el" href="class_c_time_server.html#be5e4a4628587739b7c76951f9577e8e">CTimeServer::ThreadFunctionL</a> is called within a TRAP to do the remainder of the construction that can leave. Following steps 5 -14 are executed inside of this function.</li><li>An active scheduler is required, to handle active objects. It is created</li><li>The active scheduler is installed.</li><li>An anonymous instance of <a class="el" href="class_c_time_server.html">CTimeServer</a> is created.</li><li>As all the work of the server is activated via the active scheduler, it is not necessary to refer to server. The ConstructL calls CServer::StartL.</li><li>The CServer::StartL call adds the server to the active scheduler and signals an active object request.</li><li>Semaphore is created.</li><li>Handle to the global semaphore is created.</li><li>The global semaphore is signalled. This indicates that the server has now been constructed and is ready to use. The client will return from its RSemaphore::Wait the next time that it is scheduled by the run time system.</li><li>Semaphore is closed.</li><li>The active scheduler is started by calling CActiveScheduler::Start. This function only returns when CActiveScheduler::Stop() is called, which should occur when the final client is closed. Note that an active scheduler must have a pending active object before the call to CActiveScheduler::Start() is made. This was performed in steps 7 - 9.</li></ol>
    00148 <p>
    00149 <hr>
    00150 <h3><a class="anchor" name="Sub33">
    00151 3.3 Making a server request</a></h3>
    00152 The RMessage2 class is used to transfer information between the client and the server.<p>
    00153 An instance of an RMessage2 object is automatically created for the session when the client calls the RSessionBase::SendReceive. This function can take a parameter that is a reference to TIpcArgs object, which can contain up to four 32-bit data arguments to be passed to server.<p>
    00154 The sequence involved in making a server request is shown below.<p>
    00155 <div align="center">
    00156 <img src="server_request.png" alt="server_request.png">
    00157 </div>
    00158 <p>
    00159 <ol type=1>
    00160 <li>RequestTime is called by the application in response to the user selecting the Display Time option. A reference to a TTime object is passed into this function. A descriptor is now created, representing this TTime object. This descriptor's address is added into TIpcArgs object, which is passed to the inherited SendReceive function.</li><li>The call to SendReceive results in the client thread being suspended.</li><li>SendReceive calls undocumented function from kernel side.</li><li>The kernel calls the ServiceL function of the associated server session and passes the appropriate RMessage2 object. This object specifies the operation to be performed by the server and also the message parameters. It also allows the server to indicate to the client when the request has completed, and raise a panic upon the client.</li><li>ServiceL checks the requested service using RMessage2::Function.</li><li>If requested service is ETimeServRequestTime it calls RequestTimeL, otherwise it raises a panic upon the client.</li><li>RequestTimeL calculates the current time and creates a new descriptor representing it. RMessage2::WriteL is now called with the descriptor as parameter. The first parameter of the WriteL function is index value identifying the argument. This value must be 0 because the client's descriptor is the first argument. This function call causes the time to be written to the client's address space.</li></ol>
    00161 <p>
    00162 <hr>
    00163 <h3><a class="anchor" name="Sub34">
    00164 3.4 Capabilities</a></h3>
    00165 The application does not require any capabilities. The program capabilities are defined in both mmp-files as CAPABILITY NONE. <hr>
    00166
    00167 <table x-use-null-cells
    00168                 style="x-cell-content-align: top;
    00169                                 width: 100%;
    00170                                 border-spacing: 0px;
    00171                                 border-spacing: 0px;"
    00172                 cellspacing=0
    00173                 width=100%>
    00174   <col style="width: 50%;">
    00175   <col style="width: 50%;">
    00176
    00177   <tr style="x-cell-content-align: top;"
    00178         valign=top>
    00179   <td style="width: 50%;
    00180                         padding-right: 10px;
    00181                         padding-left: 10px;
    00182                         border-right-style: None;
    00183                         border-left-style: None;
    00184                         border-top-style: None;
    00185                         border-bottom-style: None;"
    00186         width=50%>
    00187   <p style="font-family: Arial;"><small style="font-size: smaller;">© Nokia 2009</small></td>
    00188   <td style="width: 50%;
    00189                         padding-right: 10px;
    00190                         padding-left: 10px;
    00191                         border-top-style: None;
    00192                         border-bottom-style: None;
    00193                         border-right-style: None;"
    00194         width=50%>
    00195   <p style="text-align: right; margin-right: -4px;"
    00196         align=right><span style="font-weight: bold;"><a href="#Top"
    00197                                                                                                         title="Back to top"><img
    00198  src="top.gif"
    00199         x-maintain-ratio=TRUE
    00200         alt="Back to top"
    00201         style="border: none;
    00202                         width: 18px;
    00203                         height: 15px;
    00204                         float: none;
    00205                         border-style: none;
    00206                         border-style: none;"
    00207         width=18
    00208         height=15
    00209         border=0></a></span></td></tr>
    00210  </table>
    00211 </body>
    00212 </html>
    00213