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>Asynchronous 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 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>Asynchronous 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 asynchronous 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>CActive</li><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 makes use of the standard Symbian OS application framework, comprising the Application, Document, UI, and View classes. The reader should be aware of this architecture before attempting to understand this example. 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>Asynchronous programming, in particular the following topics:<ul> 00041 <li>Inter-process communication overview.</li><li>Client/server overview.</li><li>Using client/server.</li><li>CActive</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.png" alt="initial_screen.png"> 00055 </div> 00056 <p> 00057 The Options menu presents the following choices:<p> 00058 <div align="center"> 00059 <img src="options_menu.png" alt="options_menu.png"> 00060 </div> 00061 <p> 00062 <ul> 00063 <li>Select <b>Start Clock</b> to start updating the displayed time.</li><li>Select <b>Exit</b> at any time, to exit the application.</li></ul> 00064 <p> 00065 On selecting <b>Start Clock</b>, the display will be updated periodically with the current time. While the clock is running, the Options menu presents the following choices:<p> 00066 <div align="center"> 00067 <img src="options_menu_running.png" alt="options_menu_running.png"> 00068 </div> 00069 <p> 00070 <ul> 00071 <li>Select <b>Stop Clock</b> to stop updating the displayed time.</li><li>Select <b>Exit</b> at any time, to exit the application.</li></ul> 00072 <p> 00073 <hr> 00074 <h2><a class="anchor" name="Arch_sec"> 00075 2. Architecture</a></h2> 00076 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> 00077 <hr> 00078 <h2><a class="anchor" name="Design_sec"> 00079 3. Design and Implementation</a></h2> 00080 The following component diagram illustrates the split of classes over the client and server components, and their inter-relationships.<p> 00081 <div align="center"> 00082 <img src="component.jpg" alt="component.jpg"> 00083 </div> 00084 <p> 00085 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> 00086 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 three use case scenarios, where the user:<p> 00087 <ul> 00088 <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><li>Cancels a server request - the user cancels an outstanding request. This is described in the Canceling a server request section.</li></ul> 00089 <p> 00090 <hr> 00091 <h3><a class="anchor" name="Sub31"> 00092 3.1 Design overview</a></h3> 00093 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> 00094 Servers derive from CServer2, and are responsible for handling any requests from clients to establish connections.<p> 00095 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> 00096 The following class diagram shows the server-session associations for this example.<p> 00097 <div align="center"> 00098 <img src="classes.png" alt="classes.png"> 00099 </div> 00100 <p> 00101 A client can create multiple sessions with a server. However, it is more resource-efficient to use sub-sessions. This feature is not employed in this example, for simplicity.<p> 00102 The RMessage2 class is the data structure passed between client and server. The client does not manipulate this directly, as it is encapsulated in the client-side interface. Server side sessions read from, and write to, this structure to receive and send data.<p> 00103 To handle asynchronous services, the client requires the use of an active object. In this case, the active object is an instance of the <a class="el" href="class_c_c_s_async_request_handler.html">CCSAsyncRequestHandler</a> class. This is responsible for managing the asynchronous nature of this example. It issues requests (through the <a class="el" href="class_r_time_server_session.html">RTimeServerSession</a> class) for asynchronous services, and receives notification of completion through its RunL method. It uses an observer, <a class="el" href="class_m_async_time_observer.html">MAsyncTimeObserver</a>, to report the completion of requests to interested parties.<p> 00104 <hr> 00105 <h3><a class="anchor" name="Sub32"> 00106 3.2 Creating a session</a></h3> 00107 The sequence involved in creating a session is very similar to that described in the Synchronous Client/Server Example, and hence is not described in this document. The only differences in this case are that the session is created by the <a class="el" href="class_c_c_s_async_request_handler.html">CCSAsyncRequestHandler</a> class, and the number of asynchronous message slots specified in the RSessionBase::Connect call is no longer zero.<p> 00108 <hr> 00109 <h3><a class="anchor" name="Sub33"> 00110 3.3 Making a server request</a></h3> 00111 The RMessage2 and RMessagePtr2 classes are used to transfer information between the client and the server. These classes have several useful methods:<p> 00112 <ul> 00113 <li>RMessage2 allows client to specify the required server operation.</li><li>RMessage2 allows four 32-bit words of information to be passed back and forth between the client and server.</li><li>RMessagePtr2 allows the server to signal when a client's request has completed, using the Complete method.</li><li>RMessagePtr2 allows the server to panic its client.</li></ul> 00114 <p> 00115 An instance of an RMessage2 object is automatically created for the session when the client calls one of the RSessionBase::SendReceive or RSessionBase::Send methods. These methods can take a parameter that is a reference to TIpcArgs object, which can have up to four 32-bit arguments.<p> 00116 The sequence involved in making an asynchronous server request is shown below.<p> 00117 <div align="center"> 00118 <img src="requesttime.jpg" alt="requesttime.jpg"> 00119 </div> 00120 <p> 00121 <ol type=1> 00122 <li>RequestTime is called in response to the user selecting Start Clock. This calls <a class="el" href="class_c_c_s_async_request_handler.html#481d63e2f4e33b9cb8ed4680a965da25">CCSAsyncRequestHandler::RequestTime</a>.</li><li>The <a class="el" href="class_r_time_server_session.html#0e65b7c45b7af042183f1c5525cfcc1b">RTimeServerSession::RequestTime</a> is called and a TTime reference, and the active object's iStatus flag are passed to it.</li><li>A descriptor is now created, representing the supplied TTime object. This descriptor's address is entered into the TIpcArgs object, which is passed to the inherited SendReceive method. SendReceive is an asynchronous method, and returns immediately.</li><li>The SetActive method is called, to indicate that the active object has issued a request that is now outstanding. <a class="el" href="class_c_c_s_async_request_handler.html#98dcd20e4dd117488a6a90dadd4dfac5">CCSAsyncRequestHandler::RunL</a> will be called when the server completes the request.</li></ol> 00123 <p> 00124 As a result of the call to SendReceive, the framework calls the <a class="el" href="class_c_time_server_session.html#75c0a1442736b57144c9ad541d87d370">CTimeServerSession::ServiceL</a> of the associated server-side session, as shown in the following diagram.<p> 00125 <div align="center"> 00126 <img src="servicel.png" alt="servicel.png"> 00127 </div> 00128 <p> 00129 <ol type=1> 00130 <li><a class="el" href="class_c_time_server_session.html#75c0a1442736b57144c9ad541d87d370">CTimeServerSession::ServiceL</a> is called by the kernel, and passed an RMessage2 encapsulating the client's request.</li><li>RMessage2::Function is called to determine the request type.</li><li>If the request is for a time update, RequestTimeL is called.</li><li>The received request (RMessage2) is stored. The session now registers its interest in the server's time updates by calling <a class="el" href="class_c_time_server.html#a8205372b5d379fa4b803e98b0726473">CTimeServer::WaitForTickL</a>.</li><li>The server uses an instance of the CHeartbeat class to notify sessions of a time update. New instance is created here if the heartbeat is not already created.</li><li>The heartbeat is also started, if it was not already created in previous step.</li><li>When the next heartbeat occurs, <a class="el" href="class_c_time_server.html#8bc39d8613772fe04fa5d6a845ede8cd">CTimeServer::Beat</a> is called.</li><li>The Beat function calls SendTimeToSessions, which iterates over all established sessions, calling <a class="el" href="class_c_time_server_session.html#ecff8e289d914777ae0c503db937cf33">CTimeServerSession::SendTimeToClient</a>.</li><li>SendTimeToClient is called.</li><li>SendTimeToClient calculates the current time and creates a new descriptor representing it (using TPtr8 since it's binary data). RMessage2::WriteL is now called, with the created descriptor as parameter. First parameter of the WriteL is zero identifying the argument index value. The descriptor at the client side was the first argument, so server has to write into the first argument (index 0). If server writes to index 1, in this case, WriteL would return error KErrBadDescriptor. The WriteL function call causes the time to be written to the client's address space.</li><li>The server session then signals the client, using the RMessage2::Complete method. This causes the client's <a class="el" href="class_c_c_s_async_request_handler.html#98dcd20e4dd117488a6a90dadd4dfac5">CCSAsyncRequestHandler::RunL</a> method to be called, as shown in the following diagram.</li></ol> 00131 <p> 00132 Once the server has completed the request, the active object which initiated the request will be signalled, and its RunL method called, as shown in the following diagram.<p> 00133 <div align="center"> 00134 <img src="runl.jpg" alt="runl.jpg"> 00135 </div> 00136 <p> 00137 <ol type=1> 00138 <li>The active scheduler calls the RunL method in response to the server completing the request.</li><li>The observer is notified and the time is updated to the screen if the status flag indicates successful completion of the request.</li><li>A new request is scheduled, to keep the clock 'running'.</li></ol> 00139 <p> 00140 <hr> 00141 <h3><a class="anchor" name="Sub34"> 00142 3.4 Canceling a server request</a></h3> 00143 When the user selects Stop Clock, the following sequence is entered.<p> 00144 <div align="center"> 00145 <img src="cancel.jpg" alt="cancel.jpg"> 00146 </div> 00147 <p> 00148 <ol type=1> 00149 <li>CancelRequest is called in response to the user selecting Stop Clock from the Options menu.</li><li>To handle cancelled requests, active objects should call CActive::Cancel and also implement a DoCancel method. This will be called as a result of calling CActive::Cancel.</li><li>DoCancel is called, which instructs the session to cancel the outstanding request by calling <a class="el" href="class_r_time_server_session.html#52a5f2cddd36f215fea9c11e32ab88b8">RTimeServerSession::CancelRequestTime</a>.</li><li>CancelRequestTime() is called.</li><li>The synchronous request is now sent to the server, instructing it to cancel the outstanding request by calling SendReceive. The framework will call the corresponding server-side session's ServiceL method as shown in the following sequence.</li></ol> 00150 <p> 00151 As a result of the call to SendReceive, the framework calls the <a class="el" href="class_c_time_server_session.html#75c0a1442736b57144c9ad541d87d370">CTimeServerSession::ServiceL</a> of the associated server-side session, as shown in the following diagram.<p> 00152 <div align="center"> 00153 <img src="servicel-cancel.png" alt="servicel-cancel.png"> 00154 </div> 00155 <p> 00156 <ol type=1> 00157 <li>ServiceL is called by the framework in response to a request from the client.</li><li>The requested method is checked by examining the returned id from RMessage2::Function. In this case, it indicates that the client has requested cancellation of an outstanding request. The servicing of this request should complete in as short a time as possible, since the client waits for completion.</li><li>If a previous request is pending, the server completes it by calling Complete on the stored request's associated RMessage2.</li><li>The cancellation request is now completed, freeing the client to continue processing.</li></ol> 00158 <p> 00159 <hr> 00160 <h3><a class="anchor" name="Sub35"> 00161 3.5 Capabilities</a></h3> 00162 The application does not require any capabilities. The program capabilities are defined in both mmp-files as CAPABILITY NONE. <hr> 00163 00164 <table x-use-null-cells 00165 style="x-cell-content-align: top; 00166 width: 100%; 00167 border-spacing: 0px; 00168 border-spacing: 0px;" 00169 cellspacing=0 00170 width=100%> 00171 <col style="width: 50%;"> 00172 <col style="width: 50%;"> 00173 00174 <tr style="x-cell-content-align: top;" 00175 valign=top> 00176 <td style="width: 50%; 00177 padding-right: 10px; 00178 padding-left: 10px; 00179 border-right-style: None; 00180 border-left-style: None; 00181 border-top-style: None; 00182 border-bottom-style: None;" 00183 width=50%> 00184 <p style="font-family: Arial;"><small style="font-size: smaller;">© Nokia 2009</small></td> 00185 <td style="width: 50%; 00186 padding-right: 10px; 00187 padding-left: 10px; 00188 border-top-style: None; 00189 border-bottom-style: None; 00190 border-right-style: None;" 00191 width=50%> 00192 <p style="text-align: right; margin-right: -4px;" 00193 align=right><span style="font-weight: bold;"><a href="#Top" 00194 title="Back to top"><img 00195 src="top.gif" 00196 x-maintain-ratio=TRUE 00197 alt="Back to top" 00198 style="border: none; 00199 width: 18px; 00200 height: 15px; 00201 float: none; 00202 border-style: none; 00203 border-style: none;" 00204 width=18 00205 height=15 00206 border=0></a></span></td></tr> 00207 </table> 00208 </body> 00209 </html> 00210
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.