Chapter 5. The ACE Service Configurator Framework
更新时间:2023-07-20 23:28:01 阅读量: 实用文档 文档下载
- chapter推荐度:
- 相关推荐
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
Ru-Brd
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
Service Configurator framework uses to
configure and control a service
implementation. Control operations
include initializing, suspending,
resuming, and terminating a service.
ACE_Service_Repository A central repository for all services
managed using the ACE Service
Configurator framework. It provides
methods for locating, reporting on, and
controlling all of an application's
configured services.
ACE_Service_Repository_Iterator A portable mechanism for iterating
through all the services in a repository.
ACE_Service_Config Provides an interpreter that parses and
executes scripts specifying which
services to (re)configure into an
application (e.g., by linking and
unlinking DLLs) and which services to
suspend and resume.
The most important relationships between the classes in the ACE Service
Configurator framework are shown in . These classes play the following roles in accordance with the Component Configurator pattern []:
Figure 5.1. The ACE Service Configurator Framework Classes
lConfiguration management layer classes perform application-independent strategies to install, initialize, control, and shut down service objects. The classes in the configuration management layer in the ACE
Service Configurator framework include ACE_Service_Config,
ACE_Service_Repository, and ACE_Service_Repository_Iterator. Application layer classes implement concrete services to perform an application's processing. In the ACE Service Configurator framework,
application layer classes are descendants of ACE_Service_Object, which
in turn inherits from ACE_Event_Handler (), thereby enabling
service objects to be linked and unlinked dynamically, and to participate in
the ACE Reactor framework. l
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
The ACE Service Configurator framework provides the following benefits:
lFlexibility. The framework allows developers to offer multiple services, and a choice of different implementations of services, that can be assembled at run time. The choices concerning which services to execute on which
network node(s) can be made (and changed) at any point, ranging from
application build time to the actual point when services start running.
Developers can also limit choices (e.g., by not offering dynamically linkable services) where desired.
Configurability. Developers can customize and configure application data for nearly any aspect of a service and for each deployment. Services can be developed to read traditional configuration data, such as port numbers,
network addresses, and file system locations. Moreover, services can allow
tuning and performance decisions to be deferred until the right information
is available to guide them. For example, depending on the run-time
platform's available multithreading facilities and available CPUs, it may be
either more or less efficient to run multiple services in separate threads or
separate processes. The ACE Service Configurator framework enables
applications to be configured by site-knowledgable administrators, or they
can select and tune these behaviors flexibly at run time, when there's
enough information to help match client demands with available system
processing resources.
Managability. All configuration information can be stored in a configuration script file, known as svc.conf. The framework uses these scripts to load
and configure services. An application's installation procedure can record
settings in an svc.conf file. Administrators can also edit and tune this
information as needed, without rebuilding the application itself. Applications can form their own configuration directives and pass them directly to the
ACE Service Configurator framework. The framework groups an application's services into one administrative unit and enables an application to report on its services and their states.
Consistency. The framework imposes a uniform interface for initializing, suspending, resuming, and terminating a service. This uniformity provides
consistency to framework users and allows services to be treated as building blocks that can be assembled flexibly to form complete applications.
Maintainability. The framework's decoupling of service implementation from configuration into networked applications allows service
implementations to evolve over time, independently of which networked
applications they're included in. Each service can be developed and tested
independently, which simplifies subsequent service composition and
increases reuse.
Enhanced dynamism and control. The framework enables a service to be reconfigured dynamically without modifying, recompiling, or statically relinking existing code. Each service can also be reconfigured without lllll
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
affecting other services or stopping and restarting the server process itself.
These reconfiguration capabilities are often required for high-availability
applications, such as mission-critical systems that perform online transaction processing or telecom call processing.
The remainder of this chapter motivates and describes the capabilities of each class in the ACE Service Configurator framework. We also illustrate how this framework can be used to enhance the extensibility of our networked logging server. If you aren't familiar with the Component Configurator pattern from
POSA2 we recommend that you read about it first before delving into the detailed examples in this chapter.
Ru-Brd
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
are good candidates to incorporate into a framework. Enforcing a uniform interface across all networked services makes it easier to configure and manage them consistently. In turn, this consistency simplifies application development and
deployment by mitigating key challenges inherent in creating reusable administrativeconfiguration tools. To provide a uniform interface between the ACE Service
Configurator framework and the application-defined services, each service must be adescendant of a common base class called ACE_Service_Object.
Class Capabilities
ACE_Service_Object provides a uniform interface that allows service
implementations to be configured and managed by the ACE Service Configurator framework. This class provides the following capabilities:
lIt provides hook methods that initialize a service (e.g., allocating its resources)and shut a service down (e.g., cleaning up its resources).
It provides hook methods to suspend service execution temporarily and to resume execution of a suspended service.
It provides a hook method that reports key service information, such as its purpose, current status, and the port number where it listens for client
connections. ll
These methods are generally invoked as callbacks from the ACE Service Configuratorframework when it interprets the configuration directives described on page 141. The interface for ACE_Service_Object is shown in (page 120). By inheriting from ACE_Event_Handler and ACE_Shared_Object, subclasses of ACE_Service_Object can be dispatched by the ACE Reactor framework and can belinked and unlinked from a DLL dynamically, respectively. The key configuration-related hook methods of ACE_Service_Object are outlined in the following table:
Figure 5.2. The ACE_Service_Object Class
Method Description
init() Used by the framework to instruct a service to initialize itself.
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
"argc/argv"-style arguments can be passed to init() to control service
initialization.
fini() Used by the framework to instruct a service to shut itself down. This
method typically performs termination operations that release a service's
resources, such as memory, synchronization locks, or I/O handles.
suspendUsed by the framework to instruct a service to suspend and resume () execution.
resume
()
info() Used to query a service for certain information about itself, such as its
name, purpose, and network address. Clients can query a server to retriev
this information and use it to contact a particular service running in a
server.
These hook methods collectively impose a uniform interface between the ACE ServiceConfigurator framework and the application-defined services that it manages.
Application services that inherit from ACE_Service_Object can selectively overrideits hook methods, which are called back at the appropriate time by the ACE Service Configurator framework in response to specific events. For example, a service objectinit() hook method is called when the Service Configurator framework executes a directive to activate the service (both the dynamic and static directives activate aservice, as shown on page 141). The init() hook method must return 0 if initialization succeeds and -1 if it fails. If (and only if) init() succeeds, the
corresponding fini() method will be called on the service object when the ACE Service Configurator framework executes the remove directive for the service, or shuts down all services.
The Service Configurator is the first ACE framework we've studied that has extensiveinteraction with administrators or applications. These interactions introduce the needto operate with local character sets. shows the ACE_TCHAR type, which helps ACE deal with non-ASCII character sets portably. ACE's facilities for handling wide-character and Unicode characters are described in . We'll use this facility to handle character strings in the remainder of this book.
Example
To illustrate the ACE_Service_Object class, we reimplement our reactive logging server from the Example portion of . This revision can be configured dynamically by the ACE Service Configurator framework, rather than configured statically into the main() program shown on page 84. To accomplish this, we'll applthe Adapter pat-tern [] to create the following template class in the
Reactor_Logging_Server_Adapter.h header file:
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
sets in use today require more than one byte, or octet, to represent each
character. Characters that require more than one octet are referred to as
"wide characters." The most popular multiple octet standard is ISO/IEC
10646, the Universal Multiple-Octet Coded Character Set (UCS). Unicode is a separate standard, but is essentially a restricted subset of UCS that uses two octets for each character (UCS-2). Many Windows programmers are familiar with Unicode.
C++ represents wide characters with the wchar_t type, which enables
methods to offer multiple signatures that are differentiated by their character type. Wide characters have a separate set of C string manipulation functions, however, and existing C++ code, such as string literals, requires change for wide-character usage. As a result, programming applications to use wide-
character strings can become expensive, especially when applications written initially for U.S. markets must be internationalized for other countries. To
improve portability and ease of use, ACE uses C++ method overloading and the macros described below to use different character types without
changing APIs:
Macro Usage
Configuration setting to build
ACE with its wide-character
methods
Configuration setting that directs
ACE to use wide characters
internally
Defined as either char or
wchar_t, to match ACE's
internal character width
Defines the string literal str
correctly based on ACE_USES_WCHAR
Converts a char * string to
ACE_TCHAR format, if needed
Converts an ACE_TCHAR string to char * format, if needed ACE_HAS_WCHAR ACE_USES_WCHAR ACE_TCHAR ACE_TEXT(str) ACE_TEXT_CHAR_TO_TCHAR(str) (str) ACE_TEXT_ALWAYS_CHAR
ACE must be built with the ACE_HAS_WCHAR configuration setting for
applications to use wide characters. Moreover, ACE must be built with the ACE_USES_WCHAR setting if ACE should also use wide characters
internally. The ACE_TCHAR and ACE_TEXT macros are illustrated in examples throughout this book.
ACE also supplies two string classes, ACE_CString and ACE_WString,
which hold narrow and wide characters, respectively. These classes are
analogous to the standard C++ string class, but can be configured to use custom memory allocators and are more portable. ACE_TString is a
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
template <class ACCEPTOR>
class Reactor_Logging_Server_Adapter : public ACE_Service_Object {public:
// Hook methods inherited from <ACE_Service_Object>.
virtual int init (int argc, ACE_TCHAR *argv[]);
virtual int fini ();
virtual int info (ACE_TCHAR **, size_t) const;
virtual int suspend ();
virtual int resume ();
private:
Reactor_Logging_Server<ACCEPTOR> *server_;
};
This template inherits from the ACE_Service_Object class and contains a pointer a Reactor_Logging_Server object (page 83). We instantiated this template with the ACCEPTOR class parameter to defer our choice of the acceptor factory until later the design cycle. The Adapter pattern is a good choice here because it allows reuse oour existing Reactor_Logging_Server class. If we were designing this example from scratch with the ability to be configured as a service, however, a more direct approach would be to derive Reactor_Logging_Server from
ACE_Service_Object instead of from ACE_Event_Handler. In that case, the adapter class would not be needed, and we could still defer the choice of the acceptofactory until later. illustrates the lifecycle of the objects in this example when an instance of Reactor_Logging_Server_Adapter is configured dynamically. When this service configured into the address space of an application, the ACE Service Configurator framework creates an instance of Reactor_Logging_Server_Adapter and invokethe following init() hook method automatically:
Figure 5.3. Life Cycle of the Dynamic Reactor Logging Server
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
1 template <class ACCEPTOR> int
2 Reactor_Logging_Server_Adapter<ACCEPTOR>::init
3 (int argc, ACE_TCHAR *argv[])
4 {
5 int i;
6 char **array = 0;
7 ACE_NEW_RETURN (array, char*[argc], -1);
8 ACE_Auto_Array_Ptr<char *> char_argv (array);
9
10 for (i = 0; i < argc; ++i)
11 char_argv[i] = ACE::strnew (ACE_TEXT_ALWAYS_CHAR(argv[i]));12 ACE_NEW_NORETURN (server_, Reactor_Logging_Server<ACCEPTOR> 13 (i, char_argv.get (),
14 ACE_Reactor::instance ())); 15 for (i = 0; i < argc; ++i) ACE::strdelete (char_argv[i]); 16 return server_ == 0 ? -1 : 0;
17 }
Lines 5?1 The ACE Service Configurator framework passes argv as an array of ACE_TCHAR pointers, but the Reactor_Logging_Server constructor accepts a cha* array. The init() method therefore uses the ACE_TEXT_ALWAYS_CHAR macto convert to the char format where needed. This macro creates a temporary objectwith the transformed string, which is then copied via ACE::strnew() to preserve itthrough the Reactor_Logging_Server constructor. Sidebar 29 (page 125) describthe ACE::strnew() and ACE::strdelete() methods.
Lines 12?4 Dynamically allocate an instance of the Reactor_Logging_Server thacontains the desired reactor, acceptor, and handlers.
Line 15 Free the memory used for the converted argv strings.
When instructed to remove the dynamically configured logging service, the ACE Service Configurator framework invokes the
Reactor_Logging_Server_Adapter::fini()
hook method shown below:
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
template <class ACCEPTOR> int
Reactor_Logging_Server_Adapter<ACCEPTOR>::fini ()
{ server_->handle_close (); server_ = 0; return 0; }
This method calls Reactor_Logging_Server::handle_close(), which deletes thReactor_Logging_Server object allocated by init(). The ACE Service
Configurator framework uses the "gobbler" function (page 137) to delete a service object after calling its fini() hook method. We therefore must not call delete thiin fini().
The info() hook method reports service-specific information when the framework requests it. Our info() method formats a string containing the TCP port it's listeninon:
1 template <class ACCEPTOR> int
2 Reactor_Logging_Server_Adapter<ACCEPTOR>::info
3 (ACE_TCHAR **bufferp, size_t length) const {
4 ACE_TYPENAME ACCEPTOR::PEER_ADDR local_addr;
5 server_->acceptor ().get_local_addr (local_addr);
6
7 ACE_TCHAR buf[BUFSIZ];
8 ACE_OS::sprintf (buf,
9 ACE_TEXT ("%hu"),
10 local_addr.get_port_number ());
11 ACE_OS_String::strcat
12 (buf, ACE_TEXT ("/tcp # Reactive logging server\n")); 13 if (*bufferp == 0) *bufferp = ACE::strnew (buf);
14 else ACE_OS_String::strncpy (*bufferp, buf, length); 15 return ACE_OS_String::strlen (*bufferp);
16 }
Lines 4? Obtain the network address from the instance of ACE_SOCK_Acceptor that's used by the Reactor_Logging_Server.
Lines 7?2 Format a message that explains what the service does and how to contacit.
Line 13 If the caller didn't supply a buffer to hold the formatted message, allocate abuffer and copy the message into it using ACE::strnew(). In this case, the caller must use ACE::strdelete() to free the buffer. ACE does not specify how an implementation of info() must allocate memory. Developers writing an
implementation of info() must therefore define and clearly document the policy fortheir implementations. It's strongly recommended that developers use ACE::strnew
() to allocate the string, and require their users to call ACE::strdelete() to free the memory. describes the motivation for these methods.
Line 14 If the caller did supply a buffer for the message, copy the formatted messaginto it, limited to the length passed by the caller.
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
页码,11/40
Line 15 Return the length of the message. Sidebar 29: Portable Heap Operations with ACE
Library functions and classes, such as
Reactor_Logging_Server_Adapter::info() (page 124), often allocate memory dynamically. Memory allocated dynamically in C++ programs should eventually be freed. To write portable C++ programs, it's important to match these allocate and free operations to avoid corrupting the heap (also known as the freestore).
A surprisingly common misconception is that simply ensuring the proper
matching of calls to operator new() and operator delete() (or calls to malloc() and free()) is sufficient for correct heap management. This
strategy relies on the implicit assumption that there's one universal heap per process. In practice, however, a heap is simply a memory area managed by some run-time component, such as the C or C++ run-time library. If an
executing program is exposed to multiple run-time library instances, it's likely there will be multiple heaps as well.
For example, Windows supplies multiple variants of the C/C++ run-time
library, such as Debug versus Release and Multithreaded versus Single-threaded. Each of these variants maintains its own heap. Memory allocated from one heap must be released back to the same heap. Thus, correct heap management requires not only matching the proper method/function calls,
but also making them through the same run-time library. It's easy to violate these requirements when code from one subsystem or provider frees
memory allocated by another.
To assist in managing dynamic memory portably, ACE offers matching
allocate and free methods listed in the table below:
Method
ACE::strnew() Usage Allocates memory for a copy of a
character string and copies the string
into it.
Releases memory allocated by strnew
().
Allocates a memory block of specified
size.
Allocates a memory block to hold a
specified number of objects, each of a
given size. The memory contents are
explicitly initialized to 0. ACE::strdelete() ACE_OS_Memory::malloc() ACE_OS_Memory::calloc()
ACE_OS_Memory::reallocChanges the size of a memory block () allocated via
ACE_OS_Memory::malloc().
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
Unlike the other ACE_Service_Object hook methods shown in (page 120), an info() method isn't always invoked by the ACE Service Configurator
framework, though it can be. Instead, it's often called directly by a server program, shown in the Service_Reporter::handle_input() method (page 133). Moreoveapplication developers can determine the most useful content of the message since info() doesn't mandate a particular format.
The suspend() and resume() hook methods are similar to each other:
template <class ACCEPTOR> int
Reactor_Logging_Server_Adapter<ACCEPTOR>::suspend ()
{ return server_->reactor ()->suspend_handler (server_); }
template <class ACCEPTOR> int
Reactor_Logging_Server_Adapter<ACCEPTOR>::resume ()
{ return server_->reactor ()->resume_handler (server_); }
Since the Reactor_Logging_Server class descends from ACE_Event_Handler, tserver_ object can be passed to the singleton reactor's suspend_handler() and resume_handler() methods (page 73). Both methods double-dispatch to Reactor_Logging_Server::get_handle() to extract the underlying passive-mosocket handle. This socket handle is then temporarily removed from or replaced in thlist of socket handles handled by the singleton reactor. The Example portion of shows how the Reactor_Logging_Server_Adapter can be configured into anout of a generic server application dynamically.
Ru-Brd
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
页码,13/40
provided by ACE_Service_Object effectively, it must store service information in awell-known repository and be able to access and control these service objects individually or collectively.
Application services in multiservice servers also may require access to each other. Toavoid tightly coupling these services, and to preserve the benefits of delayed configuration decisions, services should be able to locate each other at run time. Therefore, to satisfy the needs of the framework and applications without requiring developers to provide these capabilities in an ad hoc way, the ACE Service
Configurator framework provides the ACE_Service_Repository and
ACE_Service_Repository_Iterator classes.
Class Capabilities
ACE_Service_Repository implements the Manager pattern [Som98] to control thlife cycle of, and the access to, service objects configured by the ACE Service Configurator framework. This class provides the following capabilities:
lIt keeps track of all service implementations that are configured into an application and maintains each service's status, such as whether it's active or suspended.
It provides the mechanism by which the ACE Service Configurator framework inserts, manages, and removes services.
It provides a convenient mechanism to terminate all services, in reverse order otheir initialization.
It allows an individual service to be located by its name. lll
The interface for ACE_Service_Repository is shown in Figure 5.4 (page 128) andits key methods are outlined in the following table:
Figure 5.4. The ACE_Service_Repository Class
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
Method Description ACE_Service_Repository() Initialize the repository and allocate its dynamic open() resources.
ACE_Service_Repository()
close()
The ACE_Service_Repository binds the following entities together:
l
The name of a service, which is represented as a character string, and
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
lAn instance of ACE_Service_Type, which is the class used by the ACE ServiceConfigurator framework to link, initialize, suspend, resume, remove, and unlinkservices from a server statically or dynamically.
The ACE_Service_Type class provides the framework with the operations necessarto act on the configured services. The ACE Service Configurator framework can be used to configure dynamic and static services, as well as the ACE_Module and ACE_Stream capabilities covered in Sections 9.2 and 9.3, respectively.
The ACE_Service_Type class uses the Bridge pattern to allow type-specific data anbehavior in service types to evolve without impacting the class. The
ACE_Service_Type class plays the Abstraction role in this pattern and the ACE_Service_Type_Impl class plays the Implementor role. The following classes each play the ConcreteImplementor role, representing the types of services that canbe recorded in the service repository:
1.ACE_Service_Object_Type桾he object() method returns a pointer to the
associated ACE_Service_Object described in .
2.ACE_Module_Type桾he object() method returns a pointer to the associated
ACE_Module described in Section 9.2.
3.ACE_Stream_Type桾he object() method returns a pointer to the associated
ACE_Stream described in Section 9.3.
For dynamically linked service objects, ACE_Service_Type also stores the handle othe DLL that contains the service's executable code. The ACE Service Configurator framework uses this handle to unlink and unload a service object from a running server when the service it offers is no longer needed. (page 131) shows how a program can use ACE_Dynamic_Service and ACE_Service_Type to retrievservices from ACE_Service_Repository programmatically.
ACE_Service_Repository_Iterator implements the Iterator pattern [GoF] to provide applications with a way to sequentially access the ACE_Service_Type itemin an ACE_Service_Repository without exposing its internal representation. The interface for ACE_Service_Repository_Iterator is shown in Figure 5.5 (page 130) and its key methods are outlined in the following table:
Figure 5.5. The ACE_Service_Repository_Iterator Class
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
Method Description
ACE_Service_Repository_IteratorInitialize the iterator.
()
next() Pass back a pointer to the next
ACE_Service_Type in the repository.
done() Returns 1 when all items have been seen.advance() Move ahead one item in the repository. Never delete entries from an ACE_Service_Repository that's being iterated over since the ACE_Service_Repository_Iterator is not a robust iterator []. Example
This example illustrates how the ACE_Service_Repository and
ACE_Service_Repository_Iterator classes can be used to implement a Service_Reporter class. This class provides a "meta-service" that clients can use obtain information on all services that the ACE Service Configurator framework has configured into an application statically or dynamically. A client interacts with a Service_Reporter as follows:
l
l
lThe client establishes a TCP connection to the Service_Reporter object. The Service_Reporter returns a list of all the server's services to the client.The Service_Reporter closes the TCP/IP connection. (page 132) describes ACE_Service_Manager, which is a class bundled with the ACE toolkit that provides a superset of Service_Reporter features. The Service_Reporter class is described below. We first create a file called Service_Reporter.h that contains the following class definition:
class Service_Reporter : public ACE_Service_Object {
public:
Service_Reporter (ACE_Reactor *r = ACE_Reactor::instance ()) : ACE_Service_Object (r) {}
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
// Hook methods inherited from <ACE_Service_Object>.
virtual int init (int argc, ACE_TCHAR *argv[]);
virtual int fini ();
virtual int info (ACE_TCHAR **, size_t) const;
virtual int suspend ();
virtual int resume ();
protected:
// Reactor hook methods.
virtual int handle_input (ACE_HANDLE);
virtual ACE_HANDLE get_handle () const
{ return acceptor_.get_handle (); }
private:
ACE_SOCK_Acceptor acceptor_; // Acceptor instance.
enum { DEFAULT_PORT = 9411 };
};
Since Service_Reporter inherits from ACE_Service_Object, it can be configureby the ACE Service Configurator framework. The ACE Service Configurator frameworwill create an instance of this class at run time, so the constructor must be public. Sidebar 30: The ACE_Dynamic_Service Template
The ACE_Dynamic_Service class template provides a type-safe way to access the ACE_Service_Repository programmatically. An application process can use this template to retrieve services registered with its local
ACE_Service_Repository. As shown below, the TYPE template parameter ensures that a pointer to the appropriate type of service is returned from the static instance() method:
template <class TYPE>
class ACE_Dynamic_Service {
public:
// Use <name> to search the <ACE_Service_Repository>.
static TYPE *instance (const ACE_TCHAR *name) {
const ACE_Service_Type *svc_rec;
if (ACE_Service_Repository::instance ()->find
(name, &svc_rec) == -1) return 0;
const ACE_Service_Type_Impl *type = svc_rec->type (); if (type == 0) return 0;
ACE_Service_Object *obj =
ACE_static_cast (ACE_Service_Object *, type->object ()); return ACE_dynamic_cast (TYPE *, obj);
}
};
If an instance of the Server_Logging_Daemon service has been linked dynamically and initialized by the ACE Service Configurator framework, an
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
页码,18/40application can use the ACE_Dynamic_Service template to access the service programmatically as shown below:
typedef Reactor_Logging_Server_Adapter<Logging_Acceptor> Server_Logging_Daemon; Server_Logging_Daemon *logging_server= ACE_Dynamic_Service<Server_Logging_Daemon>::instance (ACE_TEXT ("Server_Logging_Daemon")); ACE_TCHAR *service_info= 0; logging_server->info (&service_info); ACE_DEBUG ((LM_DEBUG,"%s\n", service_info)); ACE::strdelete (service_info);Note that this example assumes info() allocates string memory via the ACE::strnew() method discussed in Sidebar 29 (page 125).
Sidebar 31: The ACE_Service_Manager ClassACE_Service_Manager provides clients with access to administrativecommands to access and manage the services currently offered by a network server. These commands"externalize" certain internal attributes of the services configured into a server. During server configuration, an ACE_Service_Manager is typically registered at a well-known communication port, for example, port 9411. Clients can connect to an ACE_Service_Manager at that port and issue one of the following commands.l
help? a list of all services configured into an application via the ACEService Configurator framework is returned to the client.
l
reconfigure? a reconfiguration is triggered to reread the local serviceconfiguration file.
If a client sends anything other than these two commands, its input is passed to ACE_Service_Config::process_directive() (page 141), which enables remote configuration of servers via command-line instructions such as
% echo"suspend My_Service"| telnet hostname 9411It's therefore important to use the ACE_Service_Manager only if your application runs in a trusted environment since a malicious attacker can use it to deny access to legitimate services or configure rogue services in a Trojan Horse manner. For this reason, ACE_Service_Manager is a static service that ACE disables by default. An application can direct ACE to load its static services, including the
file://C:\Documents and Settings\Hank Lee\Local Settings\Temp\~hh79... PDF文件使用"pdfFactory"试用版本创建ÿÿ
2008-4-28
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
The implementations of the Service_Reporter hook methods are placed into the Service_Reporter.cpp file. The ACE Service Configurator framework calls the following Service_Reporter::init() hook method when a Service_Reporterconfigured into an application:
1 int Service_Reporter::init (int argc, ACE_TCHAR *argv[]) { 2 ACE_INET_Addr local_addr (Service_Reporter::DEFAULT_PORT); 3 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:"), 0); 4 get_opt.long_option (ACE_TEXT ("port"),
5 'p', ACE_Get_Opt::ARG_REQUIRED); 6 for (int c; (c = get_opt ()) != -1;)
7 if (c == 'p') local_addr.set_port_number
8 (ACE_OS::atoi (get_opt.opt_arg ())); 9 acceptor_.open (local_addr);
10 return reactor ()->register_handler
11 (this,
12 ACE_Event_Handler::ACCEPT_MASK);
13 }
Line 2 Initialize local_addr to the Service_Reporter's default TCP port numbeLines 3? Parse the service configuration options using the ACE_Get_Opt class described in Sidebar 8 (page 47). We start parsing at argv[0] rather than argv[1]which is the default. If the -p, or the long version --port, option is passed into ini
(), the local_addr port number is reset to that value. Since ACE_Get_Opt alwaysreturns the corresponding short option for any long options it encounters, it's sufficieto test only for 'p' in the loop iterator.
Lines 9?2 Initialize the ACE_SOCK_Acceptor to listen on the local_addr port number and register the instance of Service_Reporter with the reactor for ACCEPT events. When a connection request arrives from a client, the reactor dispatches the following Service_Reporter::handle_input() hook method: 1 int Service_Reporter::handle_input (ACE_HANDLE) {
2 ACE_SOCK_Stream peer_stream;
3 acceptor_.accept (peer_stream);
4
5 ACE_Service_Repository_Iterator iterator
6 (*ACE_Service_Repository::instance (), 0);
7
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
8 for (const ACE_Service_Type *st;
9 iterator.next (st) != 0;
10 iterator.advance ()) {
11 iovec iov[3];
12 iov[0].iov_base = ACE_const_cast (char *, st->name ()); 13 iov[0].iov_len =
14 ACE_OS_String::strlen (st->name ()) * sizeof (ACE_TCHAR);15 const ACE_TCHAR *state = st->active () ?
16 ACE_TEXT (" (active) ") : ACE_TEXT (" (paused) "); 17 iov[1].iov_base = ACE_const_cast (char *, state);
18 iov[1].iov_len =
19 ACE_OS_String::strlen (state) * sizeof (ACE_TCHAR); 20 ACE_TCHAR *report = 0; // Ask info() to allocate buffer. 21 int len = st->type ()->info (&report, 0);
22 iov[2].iov_base = ACE_static_cast (char *, report); 23 iov[2].iov_len = ACE_static_cast (size_t, len);
24 iov[2].iov_len *= sizeof (ACE_TCHAR);
25 peer_stream.sendv_n (iov, 3);
26 ACE::strdelete (report);
27 }
28
29 peer_stream.close ();
30 return 0;
31 }
Lines 2? Accept a new client connection. The Service_Reporter is an iterative service that only handles one client at a time.
Lines 5? Initialize an ACE_Service_Repository_Iterator, which we'll use to report all the active and suspended services offered by the server. Passing a 0 as thesecond argument to this constructor instructs it to also return information on suspended services, which are ignored by default.
Lines 8?7 For each service, invoke its info() method to obtain a descriptive
synopsis of the service, and send this information back to the client via the connectesocket. The sendv_n() gather-write method transfers all data buffers in the array oiovec structures efficiently using a single system function call, as discussed by Sidebar 6 in Chapter 3 of C++NPv1. Since there are no record boundaries in a TCPstream, the client may not be able to find the end of each line of text. It's therefore polite to code info() methods to include a newline at the end of the message. Notethat this code can work with either narrow or wide characters, as discussed in (page 121). The text received by the client will be in the character set and width the Service_Reporter. Designing a mechanism to handle this properly is left as anexercise for the reader.
Line 29 Close down the connection to the client and release the socket handle.
The Service_Reporter::info() hook method passes back a string that tells whicTCP port number it's listening on and what the service does:
关于ACE的详细介绍,ACE是一种跨平台的网络编程框架
int Service_Reporter::info (ACE_TCHAR **bufferp,
size_t length) const {
ACE_INET_Addr local_addr;
acceptor_.get_local_addr (local_addr);
ACE_TCHAR buf[BUFSIZ];
ACE_OS::sprintf
(buf, ACE_TEXT ("%hu"), local_addr.get_port_number ()); ACE_OS_String::strcat
(buf, ACE_TEXT ("/tcp # lists services in daemon\n")); if (*bufferp == 0) *bufferp = ACE::strnew (buf);
else ACE_OS_String::strncpy (*bufferp, buf, length);
return ACE_OS_String::strlen (*bufferp);
}
As with the Reactor_Logging_Server_Adapter::info() method (page 124), thcaller must delete the dynamically allocated buffer using ACE::strdelete().
The Service_Reporter's suspend() and resume() hook methods forward to thecorresponding methods in the reactor singleton, as follows:
int Service_Reporter::suspend ()
{ return reactor ()->suspend_handler (this); }
int Service_Reporter::resume ()
{ return reactor ()->resume_handler (this); }
The Service_Reporter::fini() method is shown below:
int Service_Reporter::fini () {
reactor ()->remove_handler
(this,
ACE_Event_Handler::ACCEPT_MASK
| ACE_Event_Handler::DONT_CALL);
return acceptor_.close ();
}
This method closes the ACE_SOCK_Acceptor endpoint and removes the
Service_Reporter from the singleton reactor. The ACE Service Configurator
framework is responsible for deleting a service object after calling its fini() hook method. We therefore don't need to delete this object in handle_close(), so wpass the DONT_CALL flag to prevent the reactor from invoking this callback. Finally, we must supply the ACE Service Configurator framework with some
"bookkeeping" information regarding this new service. Although the code for this service will be statically linked into the example program, we want the framework toinstantiate a Service_Reporter object to execute the service when it's activated. We therefore add the necessary ACE service macros to the Service_Reporter implementation file. These macros create a Service_Reporter and register it with the ACE_Service_Repository, as described in Sidebar 32 (page 136).
正在阅读:
Chapter 5. The ACE Service Configurator Framework07-20
国防大学着力重建重构重塑08-05
2号发电机大修安全技术交底07-25
初中数学竞赛知识点07-19
2014年湘教版初三数学中考模拟试题(岳阳县友爱 中学隋伟忠)09-23
少走弯路02-15
2018-2019-入党积极分子登记表考察意见-word范文 (4页)05-29
大学生暑期社会实践个人心得体会范文03-24
- 教学能力大赛决赛获奖-教学实施报告-(完整图文版)
- 互联网+数据中心行业分析报告
- 2017上海杨浦区高三一模数学试题及答案
- 招商部差旅接待管理制度(4-25)
- 学生游玩安全注意事项
- 学生信息管理系统(文档模板供参考)
- 叉车门架有限元分析及系统设计
- 2014帮助残疾人志愿者服务情况记录
- 叶绿体中色素的提取和分离实验
- 中国食物成分表2020年最新权威完整改进版
- 推动国土资源领域生态文明建设
- 给水管道冲洗和消毒记录
- 计算机软件专业自我评价
- 高中数学必修1-5知识点归纳
- 2018-2022年中国第五代移动通信技术(5G)产业深度分析及发展前景研究报告发展趋势(目录)
- 生产车间巡查制度
- 2018版中国光热发电行业深度研究报告目录
- (通用)2019年中考数学总复习 第一章 第四节 数的开方与二次根式课件
- 2017_2018学年高中语文第二单元第4课说数课件粤教版
- 上市新药Lumateperone(卢美哌隆)合成检索总结报告
- Configurator
- Framework
- Chapter
- Service
- ACE
- 基于AVL/Cruise仿真平台的汽车理论实验教学改革研究
- 银行保险的跨国比较与分析
- 阳光大桥塔吊施工方案
- 萧山区2008年小学数学青年教师解题能力竞赛
- 媒介与受众从分离走向融合
- 高级电工考试大纲
- 浅谈垦区农业信息服务平台建设
- 关节脱位病人的护理1
- 贸大金融-2015年考研真题经验解析 (10)
- 2014国家公务员考试申论热点:全球化不等于西方化
- 大大二班保育员工作计划
- 电力工程强制性条文执行计划检查表
- 2013全国统一工程量清单计量规则全套
- 品社备课(五年级三单元一课)玲玉
- 历下区老教师第五届乒乓球比赛秩序册
- 校园周边环境排查治理整改汇报材料
- 剂型聚丙烯酸酯压敏胶合成工艺的研究
- 综合英语B2离线作业
- 南岸区小学语文“识字教学与书法教育”研讨活动
- 水工钢筋混凝土课程设计教学大纲