ThreadServer.h 

This sample program is for Microsoft Windows developers, and shows how the class library can be used with the MFC to provide a user interface. For more information, please see the detailed comments in each program and the documentation for each class library function.

 

/********************************************************************

// Multithreading server test program.

// Multithreading only works for systems running 32-bit Windows.

// To write a multithreading server program for a server function

// derived from CRfcServerFunc, you need to implement a clone

// function. This clone function needs to dynamically duplicate

// itself.

// Before you begin, define a copy constructor for your derived

// class. This makes it easier to implement the clone function.

// Please see the code example below if you need more information.

//

// To use the multihreading server feature, follow this step-by-step

// example:

//

// (1) Derive a class from CRfcServerFunc. In this example, it is

// called CRfcShow.

// (2) Derive a class from CRfcServerApp. In this example, it is

// called CRfcMyApp.

// (3) In the CRfcShow class, define your own import, export, and

// table

// parameters.

// (4) Implement the virtual functions CRfcShow::Process(void) and

// CRfcShow::GetDescription (void).

// (5) Implement a constructor, copy constructor, and a destructor

// for CRfcShow.

// (6) Implement the function CRfcServerFunc::clone in the CRfcShow

// class. We did not define it as a pure virtual function

// because we do not want to force non-multithreading server

// users to implement it. However, if you want to use the

// multithreading feature, you will receive an error if you

// implement this clone function in your derived class (for

// example, CRfcShow).

// (7) If you just want to use the multithreading server feature,

// then you do not need to define anything for CRfcMyApp. If

// this is the case, you can go directly to step 8. However,

// if you also want your application to work using a single

// thread, then you need to implement CRfcMyApp::OnIdle().

//

// Warning: If you do not implement this function, and you

// design your application to use a single thread, your

// application will take over most of your available CPU!

//

// (8) Create a CRfcConnection object, a CRfcMyApp object, and a

// CRfcShow object.

// (9) Connect to the R/3 system by calling CRfcConnection::Accept

// (argv), where argv is the command line argument.

// (10) Install the RFC function by calling

// CRfcServerApp::AddServerFunction (RfcShow), where RfcShow is

// an object of CRfcShow.

// (11) Call CRfcServerApp::Run(nThreads), where nThreads is the

// number of child threads you want.

//

// Note: If you enter a zero or no input as the value of

// nThreads, the application will not use multithreading.

//

// Tips for Selecting the Number of Threads

//

// Case 1: The server has only one CPU. It is very unlikely that

// more than one client will call this server

// simultanously. If so, do NOT use multithreading. You

// can call Run without an argument, or use zero as the

// argument.

// Case 2: The server has more than one CPU. Usually, there will

// be only one client at a time calling this server. Do

// NOT use multithreading.

// Case 3: The server has more than one CPU. There might be more

// than one client calling the server simultaneously.

// However, the number of clients is usually smaller than

// the number of CPUs. Set the number of child threads,

// nThreads, equal to the number of CPUs.

// Case 4: The server has one or more CPUs. Usually, the number of

// clients calling the server is greater than the number of

// CPUs. In this instance, you need to select the number of

// child threads experimentally.

********************************************************************/

 

#if !defined(CRSERVTH_H)

#define CRSERVTH_H

#include "CRfcglob.h"

#include "CRfclass.h"

#if defined(_WIN32) || defined(SAPonNT)

#define CRFCwithTHREADS

#include <conio.h>

#endif

 

void DumpErrorInfo (RFC_ERROR_INFO& err)

{

CRfcString errMessage;

errMessage = "RFC Error: \nKey:";

errMessage += err.key;

errMessage += "\nStatus:";

errMessage += err.status;

errMessage += "\nMessage:";

errMessage += err.message;

printf("%s\n\n", errMessage);

}

void get_passwd(char * pwd);

class CrServTh

{

// Construction

public:

CrServTh(void); // standard constructor

~CrServTh(void);

void DoMultithreading(char** argv, int nThreads=0);

private:

void StartThreads(char** argv, int nThreads=0);

};

const int TEXT_LEN = 80 ;

// Declare the server function.

// The import data for this function is that for the RFC function

// called by this server. This server will then get the export and

// table data, and pass it to the clients.

class CRfcMyApp;

class CRfcShow: public CRfcServerFunc

{

// constructor & destructor

public:

CRfcShow() ;

CRfcShow(CrServTh * pServTh, CRfcMyApp *pApp) ;

~CRfcShow() ;

//Attributes

protected:

CRfcSimpleParam* m_pSimTitle ;

CRfcSimpleParam* m_pSimCount ;

CRfcTableParam * m_pTabContents ;

CrServTh * m_pServTh;

CRfcMyApp * m_pApp;

void ClearParams(void);

public:

//Process() is declared as pure virtual,

//so it must be implemented by users.

void Process (void) ;

CRfcServerFunc * clone() {return new CRfcShow(*this);}

//This function must be implemented in the derived class of

//CRfcServerFunc to make multithreading work

CRfcShow(const CRfcShow & pShow);

//This copy constructor must be implement to make the above

//clone function work

//Documenting the function object so that infomation about

//the function is available when requested from R/3 System

char* GetDescription (void) ;

void SetnThreads(int nThreads) {m_nThreads = nThreads;}

private:

//Table filed information about CONTENTS

static RFC_FIELD_INFO FieldsCONTENTS[] ;

int m_nThreads;

};

//Declare the server app

class CRfcMyApp: public CRfcServerApp

{

// constructor & destructor

public:

CRfcMyApp(CRfcConnection* pConnection = NULL) ;

~CRfcMyApp() ;

void OnIdle();

void EnableIdlePrint();

private:

BOOL m_bPrintWait;

};

#if defined(SAPonHPPA)

template class CRfcList<CRfcString>;

#endif

#endif !defined(CRSERVTH_H)