This page was last modified 03:18, 22 March 2008.
Implementing asynchronous requests
From Forum Nokia Wiki
| ID | Creation date | March 21, 2008; | |
| Platform | S60 3rd Edition, S60 3rd Edition FP1; | Tested on devices | |
| Category | Client/Server; | Subcategory |
| Keywords (APIs, classes, methods, functions): |
This example shows how to implement asynchronous requests in client/server communication. It shows both the server and its client counterpart implementation.
Overview
Symbian OS programming is event-based. Symbian architecture is composed by several servers that provide access to resources to its clients, the applications. They should provide APIs to event-based programming that consists of asynchronous requests.
Asynchronous requests are made to servers in a way that the response is obtained later, usually through an Active object. This example shows how this kind of request can be implemented by the server.
Preconditions
The reader should be familiarized with Symbian Client-Server Framework.
The reader should also know the basics about implementing servers. See How to create a server from scratch and Client side implementation of a server for more information.
Client side implementation (R class)
The main characteristic in the method signature of a asynchronous request, when compared with a synchronous request is a parameter, an object of type TRequestStatus. This object keeps the state of the request and is owned by the client. The server access it directly to update the state of the request so that the client can know when the request has completed or an error occurred. The header file of the R class is showed bellow. It presents a simple example API that has only one asynchronous request, AsyncRequest, and one synchronous request, CancelAsyncRequest.
// CLASS DECLARATION /** * RExampleServerSession * This class provides the client-side interface to the server session */ class RExampleServerSession: public RSessionBase { public: // Constructors and destructors /** * RExampleServerSession. * Constructs the object. */ RExampleServerSession(); public: // New functions /** * Connect. * Connects to the server and create a session. * @return Error code. */ TInt Connect(); /** * Version. * Gets the version number. * @return The version. */ TVersion Version() const; /** * AsyncRequest. * Issues a request to the server. * @param aStatus The TRequestStatus object to be used for async comms. */ void AsyncRequest( TRequestStatus& aStatus ); /** * CancelAsyncRequest. * Cancels any outstanding request to the server. */ void CancelAsyncRequest() const; };
Talking about the implementation, the only difference that can be found from the synchronous implementation is the presence of one more parameter when calling the base class SendReceive method, the TRequestStatus. One thing to be noted is that both, synchronous and asynchronous function calls returns immediately. The difference is that in the synchronous function call, the information is obtained immediately, and in the asynchronous function call, the information is obtained later. The implementation of the requests is presented bellow.
// ----------------------------------------------------------------------------- // RExampleServerSession::AsyncRequest() // Issues a request to the server. // ----------------------------------------------------------------------------- // void RExampleServerSession::AsyncRequest( TRequestStatus& aStatus ) { SendReceive( EExampleServAsyncRequest, args, aStatus ); } // ----------------------------------------------------------------------------- // RExampleServerSession::CancelAsyncRequest() // Cancels any outstanding request to the server. // ----------------------------------------------------------------------------- void RExampleServerSession::CancelAsyncRequest() const { SendReceive( EExampleServCancelAsyncRequest, TIpcArgs(NULL) ); }
Common File
The Operation Codes (also called Op codes) need to be shared among server and client. We can see the use of these codes on the implementation of the R class in the SendReceive method. They are used by both server and client as an agreement of what information is being requested by the user of this client/server implementation. This information (Op codes) is shared among client and server implementations through a common header file. An example of this file is presented next.
// DATA TYPES // Opcodes used in message passing between client and server enum TExampleServRqst { EExampleServAsyncRequest, EExampleServCancelAsyncRequest }; // Opcodes used by server to indicate which asynchronous service // has completed enum TExampleServRqstComplete { EExampleServAsyncRequestComplete = 1 };
Server side implementation
There are few changes between the implementation of a server that has only synchronous request and a server that has also asynchronous requests. The server object, derived from CServer2 class, is praticaly the same. The main difference is in the ServiceL method of the session object derived from the CSession2. Bellow follow the source file of the main methods of the session class.
void CExampleServerSession::ServiceL( const RMessage2& aMessage ) { switch ( aMessage.Function() ) { case EExampleServAsyncRequest: //Op code defined in common header AsyncRequestL( aMessage ); //method that makes the asynchronous request break; case EExampleServCancelAsyncRequest: //Op code defined in common header if ( iWaitingAsyncRequest ) { iMessage.Complete( KErrCancel ); //Completing the request with a cancel code iWaitingAsyncRequest = EFalse; } aMessage.Complete( KErrNone ); break; default: break; } } /** Makes the request here. Don't call complete in the aMessage since this is a * asynchronous request. */ void CExampleServerSession::AsyncRequestL( const RMessage2& aMessage ) { //1. Test if there is also a pending request. if yes panic, only one can exist //2. Makes the request //3. Stores the message to complete it later, when the request is ready iMessage = aMessage; //4. Sets the flag iWaitingAsyncRequest = ETrue; } /** The asynchronous request is ready in this function. Must complete the pending request * and to signal the client the server completed the request. */ void CExampleServerSession::AsyncRequestCallBack( ) { if( iWaitingAsyncRequest ) { // 1. Obtain the information required by the user. // 2. Signals the user about the completion of this request. This different Op code for //the answer allow the AO to differentiate among various asynchronous requests. iMessage.Complete( EExampleServAsyncRequestComplete ); iWaitingAsyncRequest = EFalse; } }
The first method shows the dispatcher of the requests. It switches each request to a different operation based on the Op codes defined in the common header file. When a asynchronous request comes, the session don't complete (call Complete) message and storing it to complete later (it is an asynchronous call). The Cancel request, completes two requests, the pending request (represented by the iMessage msg), if there is any, and the wn call to the cancel, that is a message also. As the call to cancel is synchronous, it shoud be completed immediately.
The second method makes the requests, stores the message and sets a flag so the session object knows there is a pending request.
The third method deals with the completion of the pending request. It calls the Complete mehtod in the stored message and resets the flag so this session can receive more asynchronous calls.
Postconditions
This code snippet shows how to implement an asynchronous call to a Symbian server. The reader should be able to create its own asynchronous calls after reading this article.
| Related Discussions | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Different between WAP AP & Internet AP? | KK_Dog | Symbian Networking & Messaging | 2 | 2004-02-05 03:11 |
| How to hide RNotifier ? | yaohongwang | General Symbian C++ | 2 | 2007-11-26 05:26 |
| Using active objects without synchronized service | er_benji | General Symbian C++ | 6 | 2007-09-18 08:31 |
| Creating a background thread | pawel_z | General Symbian C++ | 7 | 2003-10-08 16:33 |
| Getting caller ID | stanescu | General Symbian C++ | 1 | 2004-08-22 11:06 |
