RealServer plug-ins can monitor resources in the RealServer Property Registry, which is a dynamic repository for a variety of server and client properties. These properties include such values as the number of clients currently connected, the total bandwidth being utilized, and a comprehensive set of statistics for each of these clients. A monitor plug-in can monitor any registry property, receiving notification when RealServer updates the property. Monitor plug-ins can also add their own properties to the registry and receive notifications when those properties change.
![]() |
Additional Information |
---|
For a detailed description of the RealServer Property Registry, including descriptions of the various server, client, and session properties, see "Appendix F: RealServer Property Registry". |
Monitor plug-ins do not need to be standalone modules. Any server-side plug-in can implement the monitoring features described in this section. A file format plug-in, for example, can check the registry for customized configuration parameters.
![]() |
Additional Information |
---|
For information on receiving system error messages, See "Chapter 15: Status Codes and Errors". |
A monitor plug-in implements the following interfaces:
IRMAPlugin
. Header file: rmaplugn.h
. Every plug-in implements this interface, which RealSystem uses to determine the plug-in's characteristics.
IRMAPropWatchResponse
. Header file: rmamon.h
. When it updates monitored resources in its registry, RealServer uses this interface to notify the plug-in.
IRMACallback
. Header file: rmaengin.h
. If the plug-in uses RealSystem Scheduler, it implements this interface to receive callbacks at designated intervals.
The monitor plug-in uses the following interfaces:
IRMAPNRegistry
. Header file: rmamon.h
. A monitor plug-in uses this interface to access and watch information in the RealServer registry.
IRMAPropWatch
. Header file: rmamon.h
. This interface allows the monitor plug-in to set and clear watches on properties within the RealServer registry. RealServer sends notifications to the plug-in through the IRMAPropWatchResponse
interface.
IRMAScheduler
. Header file: rmaengin.h
. The plug-in uses this interface to schedule callbacks from the RealSystem Scheduler.
![]() |
Note |
---|
RealServer interfaces do not provide methods for logging or writing information to disk or remote destinations. Monitor plug-ins are responsible for managing any needed data handling. |
The following sections explain how RealServer and a monitor plug-in use the RealSystem interfaces. The sample code included with this SDK illustrates many of these features. You can use the sample code as a starting point for building your own plug-in. Refer to the RealSystem SDK header files for more information on function variables and return values.
When RealServer starts up, it loads each monitor plug-in:
RMACreateInstance
to create an instance of the monitor plug-in. See "Creating a Plug-In Instance" for more on this method.
IRMAPlugin::GetPluginInfo
, which returns descriptive information used by the RealSystem client. A plug-in used only for monitoring can return NULL
for all descriptive values except pDescription
, which should be Monitor
. Set bLoadMultiple
to FALSE
to open the monitor plug-in in the RealServer process.
IRMAPlugin::InitPlugin
, passing the monitor plug-in a pointer to the RealServer context. Within IRMAPlugin::InitPlugin
, the plug-in peforms any necessary initialization, minimally doing the following:
IRMACommonClassFactory
so that it can create RealSystem objects.
IRMACommonClassFactory::CreateInstance
to get an IRMAPNRegistry
interface.
IRMAPNRegistry::CreatePropWatch
to create an IRMAPropWatch
interface. This interface lets the monitor plug-in set watch points on properties.
IRMAPropWatch::Init
, the plug-in initializes the property watch interface with the response interface, IRMAPropWatchResponse
, which is the monitor plug-in itself. Through the response interface's methods, RealServer notifies the plug-in of additions, modifications, and deletions to the watched properties.
IRMAPropWatch
(see "Watching Properties") or IRMAScheduler
(see "Using the Scheduler"). The sample code uses a method called CExampleMonitor::SetWatches
, but you can use any other method name. The plug-in methods are called when watches are triggered or, if a callback has been put into the Scheduler, whenever the time slice expires.
The RealServer implementation of monitoring enables monitor plug-ins to watch desired resources much as a debugger does. You can set watches on composites or any other type of property, but there is a subtle difference between the two. For composite properties, RealServer sends notification only when one of the following happens:
For all other properties, RealServer sends notification on one of the following:
Use IRMAPropWatch::SetWatchOnRoot
to watch for additions or deletions of properties at the registry's root level. To set watches on specific properties, use one of these methods:
When RealServer adds, modifies, or deletes the watched property, it notifies the plug-in through the IRMAPropWatchResponse::AddedProp
, IRMAPropWatchResponse::ModifiedProp
, and IRMAPropWatchResponse::DeletedProp
methods. This notification includes the watched property's ID value, its datatype, and the ID of its parent property. The plug-in can then query the registry for the property's new value.
Keep in mind the following when setting watches:
IRMAPNRegistry
methods (such as IRMAPNRegistry::GetIntByName
or IRMAPNRegistry::GetIntById
) or use the IRMAScheduler
interface along with IRMACallback
.
![]() |
Additional Information |
---|
See "Using the Scheduler". |
IRMAPropWatch::SetWatch
xxx methods set watches on properties, IRMAPropWatch::ClearWatch
xxx methods are available to clear the watches when necessary.
From the system context pointer it receives during initialization, a plug-in can use IUnknown::QueryInterface
to obtain the IRMAScheduler
interface. The plug-in then creates an IRMACallback
interface and enters it into the Scheduler using one of these methods:
IRMAScheduler::AbsoluteEnter
, an absolute time defined by the RMATimeval
structure.
IRMAScheduler::RelativeEnter
, the number of milliseconds from the current time.
The Scheduler then calls IRMACallback::Func
after the specified time slice has elapsed. See the monitor plug-in sample code for an example of one way to do this.
The RealSystem SDK includes two monitor plug-in samples: an intermediate sample and an advanced sample.
The RealSystem SDK includes source code for a sample monitor plug-in you can use as a template:
samples/intermed/exmonpln/exmonpln.cpp
This sample plug-in monitors active RealServer connections and displays the information on the console of the RealServer machine.
Modify the sample code as follows.
CExampleMonitor::GetPluginInfo
method.
![]() |
Note |
---|
Do not change the pDescription attribute. It must be Monitor .
|
CExampleMonitor::
PrepareCounter
CExampleMonitor::
UpdateCounter
CExampleMonitor::SetWatches
method to specify the properties you want to monitor.
CExampleMonitor::
AddedProp
CExampleMonitor::ModifiedProp
CExampleMonitor::
DeletedProp
![]() |
Tip |
---|
Limit the amount of processing within methods to prevent slowing down RealServer. |
The sample samples/advanced/expksink/expksink.cpp
is an example of a live packet sink plug-in that uses monitoring. It sets a watch on the registry's
LiveConnections
composite key so that it will receive notifications about new live connections. It then examines the headers and packets sent to the server from the live source. The plug-in can use this information for many purposes, including logging statistics about the live content or archiving the live streams to disk. See the source file for instructions on how the plug-in works.
The following example shows how to add an IntRef property. It demonstrates how the property creator can change its value using a simple "C"-style dereference:
// creator
int* int_val = new int;
*int_val = 99;
...
UINT32 iref_id = m_registry->AddIntRef("mystats.foobar", int_val);
...
/*
modifying the variable pointed to by int_val automatically reflects
in the registry because it is the same address.
*/
(*int_val)++;
...
// accessor -- some other user
INT32 i_val = 0;
m_registry->GetIntByName("mystats.foobar", i_val);
...
This next example adds registry statistics that show how many clients are connected per hour and how many packets are lost per hour.
char *str[] = { "mystats",
"mystats.num_player_per_hour",
"mystats.packets_lost_per_hour"
};
// add the COMPOSITE under which our INTEGER Props will go
mystats_id = m_pRegistry-AddComp(str[0]);
npph_id = m_pRegistry-AddInt(str[1], num_plyrs_per_hr);
plph_id = m_pRegistry-AddInt(str[2], pckts_lost_per_hr);
...
if (m_pRegistry->SetIntById(npph_id, num_plyrs_per_hr) != PNR_OK)
{
// error reporting here...
}
This code adds the composite property mystats
to the registry. This property contains the two string properties mystats.num_player_per_hour
and mystats.packets_lost_per_hour
. To retrieve the values of the properties you can do either of the following:
int int_val = 0;
if (m_pRegistry->GetIntByName(str[1], int_val) != PNR_OK)
{
// do some error checking here
}
int int_val = 0;
if (m_pRegistry->GetIntById(npph_id, int_val) != PNR_OK)
{
// do some error checking here
}
For a string, retrieve the value as follows:
IRMABuffer
* str_val = 0;
if (m_pRegistry->GetStrByName(prop_name, str_val) != PNR_OK)
{
// error checking here
}
// after you are done with the buffer RELEASE it
str_val-Release()
;
![]() |
Note |
---|
When retrieving string values, make sure that you pass in a pointer to an
IRMABuffer that has not been created. RealServer returns a created buffer
with the string value in it. Be sure to use IUnknown::Release to release the
buffer after using it.
|
To get the unique ID value of a property, pass the property name to the IRMAPNRegistry::GetId
method. If the property does not exist, the method returns 0 (zero) as the ID.