Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Symbian OS Explained - Effective C++ Programming For Smartphones (2005) [eng].pdf
Скачиваний:
70
Добавлен:
16.08.2013
Размер:
2.62 Mб
Скачать

SERVER SHUTDOWN

213

Incidentally, a constant reference to the RMessage associated with

the request is passed into each of

the

request handler methods

but

it may, alternatively, be retrieved

by

the handler methods by

call-

ing CSharableSession::Message(). However, the asynchronous requests must store a copy of the RMessage object, because the session may be processing another, different, request message by the time the asynchronous request completes and is handled.

12.6 Server Shutdown

The timer class which manages server shutdown is shown below:

const TInt KShutdownDelay=200000; // approx 2 seconds

class CShutdown : public CTimer

{

public:

inline CShutdown(); inline void ConstructL(); inline void Start();

private:

void RunL(); };

inline CShutdown::CShutdown()

: CTimer(-1) {CActiveScheduler::Add(this);}

inline void CShutdown::ConstructL() {CTimer::ConstructL();}

inline void CShutdown::Start() {After(KShutdownDelay);}

void CShutdown::RunL()

{// Initiates server exit when the timer expires CActiveScheduler::Stop();

}

The CServer-derived object owns a CShutdown object. As I described above, the server reference-counts its connected client sessions. The shutdown timer object is started when there are no sessions connected to the server, although it is canceled if a session connects before the timer expires. When the timeout completes, the timer’s event handler calls CActiveScheduler::Stop() to terminate the server’s wait loop and destroy the server. The timeout is used to delay shutdown and prevent excessive startup/shutdown churn caused by client connections which do not quite overlap. The server’s shutdown timeout is defined by KShutdownDelay, which is set to 2 seconds.

214THE CLIENT–SERVER FRAMEWORK IN PRACTICE

12.7Accessing the Server

Finally, for reference, here is an example of how the Hercules server may be accessed and used by a client. The client-side RHerculesSession class is used to connect a session to the server and wrap the caller’s parameter data as appropriate, before passing it to the server.

void TestClientServerL()

{

__UHEAP_MARK; // Checks for memory leaks (see Chapter 17) RHerculesSession session; User::LeaveIfError(session.Connect()); CleanupClosePushL(session); // Closes the session if it leaves

_LIT8(KLionDes, "NemeanLion"); User::LeaveIfError(session.SlayNemeanLion(KLionDes, 1));

TVersion version(1,0,0); THydraData hydraData; hydraData.iHydraVersion = version; hydraData.iHeadCount = 9;

User::LeaveIfError(session.SlayHydra(hydraData));

... // Checks hydraData, which was modified by the server

TInt count;

User::LeaveIfError(session.CaptureCeryneianHind(count));

... // Checks count which was set by the server

CHerculesData* data =

CHerculesData::NewLC(_L8("test1"), _L8("test2"), 1);

User::LeaveIfError(session.SlayErymanthianBoar(*data));

TRequestStatus status; session.CleanAugeanStables(status); User::WaitForRequest(status);

// Server reads this data and updates it TBuf8<12> myBuf(_L8("testdata")); session.SlayStymphalianBirds(3, myBuf, status); User::WaitForRequest(status);

... // Inspects the contents of myBuf, modified by the server CleanupStack::PopAndDestroy(2, &session); // data, session __UHEAP_MARKEND;

}

12.8Summary

This chapter examined code for a typical client–server implementation, using a simplistic example to avoid introducing ”accidental complexity”. It is intended for those wishing to implement a server and its client-side access code, and to illustrate how the Symbian OS client–server architecture works in practice, reinforcing the theory described in Chapter 11.

SUMMARY

215

The example is a transient server that runs in a separate process from its clients, with the client-side implementation in a separate DLL. The chapter discusses best practice in the following areas of code:

the use of ”opcodes” to identify a client request

a typical client-side RSessionBase-derived class and its ”boilerplate” code to submit requests to the server. The discussion included details of how to submit different types of parameter data to the server:

simple built-in types

descriptors

flat data (such as that contained in a struct or an object of a T class)

more complex objects, which do not have a fixed length or which contain pointers to other objects (e.g. an object of a C class).

how to implement client-side code to start the server (which for EKA1 is different depending on whether the server is running on the Windows emulator or target hardware) and how to connect to the server

server-side bootstrap code

the fundamental server classes, deriving from CServer and CSharableSession, including examples of request-handling methods (for both synchronous and asynchronous requests), server-side unpacking of parameter data passed from the client, and an example of how data can be passed back to the client

the mechanism used by a transient server to reference-count its connected client sessions and shut itself down, after a brief timeout, when all its clients have disconnected

the implementation of a typical calling client that instantiates an object of the RSessionBase-derived client class and submits requests to the server.

This chapter also listed the twelve labors of Hercules, which the reader may, or may not, wish to commit to memory.