Table of Contents
TCP/IP is commonly used to communicate with third party products, like billing systems, for example. However, care must be taken to avoid blocking the main thread of the program.
One option is to spawn separate threads to handle the I/O, but the recommended option is to use non-blocking I/O. Mercury uses non-blocking I/O by default, and provides callbacks on I/O events to enable the program to wait for something without blocking the main thread.
The Mercury::EventDispatcher
class contains
the main loop of almost all the server executables:
Mercury::EventDispatcher::processContinuously()
.
This function effectively time slices the main thread by waiting for events to happen on sockets, and then calling handlers to process those events. It is vital that all event handler does not to block or take a significant amount of processing time, otherwise the others will be starved.
The following Mercury::EventDispatcher methods allow event handlers to be registered:
-
registerFileDescriptor
bool registerFileDescriptor( int fd, InputNotificationHandler * handler );
-
deregisterFileDescriptor
bool deregisterFileDescriptor( int fd );
-
registerWriteFileDescriptor
bool registerWriteFileDescriptor( int fd, InputNotificationHandler * handler );
-
deregisterWriteFileDescriptor
bool deregisterWriteFileDescriptor( int fd );
The handleInputNotification method of an InputNotificationHandler object registered via registerFileDescriptor will be called when the specified file descriptor (usually a socket) has data available for reading.
The handleInputNotification
method of an
InputNotificationHandler
object registered via
registerWriteFileDescriptor
will be called when
the specified file descriptor (usually a socket) is ready for writing.
This is useful when writing a large amount of data. A non-blocking write
operation will only write an amount of data equal to, or less than, its
internal buffers can hold. Then the program must wait until the socket is
again ready to be written to. Waiting for a socket to become writable is
also useful during the TCP connection process, as the socket will not be
ready for writing until the connection is fully established.
All registered handlers must be de-registered using the corresponding function. They are not automatically de-registered when the file descriptor is closed.
For more details, see the example file
bigworld/src/server/baseapp/eg_tcpecho.cpp
.