Class DDispatcher



DDispatcher inherits from DClient, and extends it by separating the TCP data into distinct messages. DDispatcher will call an event handler whenever a complete message is received, removing the need to deal with partial messages. (See the Event Handling section for more.) This comes at a small overhead; the message size, and a 3-byte header that allows us to recover if the TCP stream is corrupted.

Furthermore, the DDispatcher allows us to split a single TCP connection into seperate 'channels'. We can address messages with a 1-byte type and a 2-byte subtype, giving us over 16 million possible identifiers. The addHandler functions let you specify which event handler should run whenever a message with a given type is received. If no type is specified, the DDispatcher won't send any type information over the network, to maintain minimal overhead per message. Likewise, if the subtype isn't specified we don't bother sending it.

DClient's setReceiveHandler function is masked by DDispatcher; use one of the addHandler functions instead.

Constructors

Networking Methods

UDP Networking


DDispatcher(DEngine *engine)

The default constructor creates a DDispatcher that's registered with the given engine. This constructor should be used when connecting to a server.


DDispatcher(DEngine *engine, unsigned int bufferSize)

Same as above, but allows us to set the size of the DDispatcher's send and receive buffers to bufferSize bytes. Larger buffer sizes can result in better efficiency. The default size is 16 kilobytes, which is already quite large for most networks.


DDispatcher(DEngine *engine, boost::asio::ip::tcp::socket *socket)

This constructor should be used in DServer's connectHandler function. newSocket is a connection that was accepted by the DServer, and will be used by the created DDispatcher.


DDispatcher(DEngine *engine, boost::asio::ip::tcp::socket *socket, unsigned int bufferSize)

Same as above, but allows us to set the size of the DDispatcher's send and receive buffers to bufferSize bytes. Larger buffer sizes can result in better efficiency. The default size is 16 kilobytes, which is already quite large for most networks.


void addHandler(boost::function<void (DBuffer&)> handler)

Adds an event handler that will be called whenever any message is received. It no longer makes sense to call the other versions of addHandler; this version will treat their type and subtype headers as the first part of the received message, and their event handlers will never be called. This function throws an exception if the other versions of addHandler have been called already.


void addHandler(uint8_t messageType, boost::function<void (DBuffer&)> handler)

Add an event handler for all messages with the given messageType. Throws an exception if you've previously set subtype handlers for this messageType.

addHandler(1, 12, &aHandler);
addHandler(1, 13, &bHandler);
addHandler(1, &cHandler);//throws exception, message type 1 has subtypes
addHandler(2, &dHandler);//this is fine


void addHandler(uint8_t messageType, uint16_t subType, boost::function<void (DBuffer&)> handler)

Add an event handler for all messages with the given messageType and subType. Throws an exception if you've previously set a handler for this messageType that did not take a subType.


bool flush(void)

Immediately sends any buffered data over the network. Returns false if there was no data to be flushed. flush has no effect if Nagle's algorithm is enabled, since the DDispatcher is not managing the send buffer in that case. flush is automatically called along with the DEngine's update function.

Neither flush nor Nagle's algorithm have any effect on UDP data, which is always sent immediately.


void removeHandler(void)

void removeHandler(uint8_t messageType)

void removeHandler(uint8_t messageType, uint16_t subType)

Remove an event handler that was added with the equivalent addHandler function. Throws an exception if a handler does not exist for the specified messageType and subType.


void sendTcp(const DBuffer &message)

Sends a generic message to the remote host. Unlike DClient, the message is not sent immediately if Nagle's Algorithm is disabled. If many TCP messages need to be sent at the same time, the DDispatcher will bundle them and send them together when flush is called. This lets us reduce bandwidth without increasing latency, since we can call flush immediately after the messages are assembled.


void sendTcp(uint8_t messageType, const DBuffer &message)

Sends a message with the specified messageType to the remote host. messageType 255 is reserved for internal use and should not be used.


void sendTcp(uint8_t messageType, uint16_t subType, const DBuffer &message)

Sends a message with the specified messageType and subType to the remote host. messageType 255 is reserved for internal use and should not be used.


unsigned long int unsentBytes(void)

Returns the number of bytes that are queued for sending over TCP.


void disableUdp(void)

Disables UDP networking if it's currently enabled.


bool requestUdp(DUdpModule *udpModule, uint16_t remotePort, boost::function<void (UdpStatus)> udpResultHandler)

Request UDP communication with the remote host. The DDispatcher should be connected before calling this method, and the udpModule should already be bound to a port.

We're asking the remote host to bind a DUdpModule to remotePort, which will communicate with our udpModule alongside our existing TCP connection. udpResultHandler will be called when we receive an acknowledgement from the remote host, with UdpStatus set to one of the following values:

It is safe to delete the DUdpModule while UDP communication is active. It will automatically notify our DDispatcher that UDP communication is now disabled.

Note that calling requestUDP will result in a call to sendHandler, as the UDP request is sent over TCP.

requestUDP returns false if the udpModule is not bound to a port, and true otherwise.


void sendUdp(const DBuffer &message)

Sends a generic message to the remote host. Up to 65507 bytes can be sent at a time.


void sendUdp(uint8_t messageType, const DBuffer &message)

Sends a message with the specified messageType to the remote host. Up to 65507 bytes can be sent at a time. messageType 255 is reserved for internal use and should not be used.


void sendUdp(uint8_t messageType, uint16_t subType, const DBuffer &message)

Sends a message with the specified messageType and subType to the remote host. Up to 65507 bytes can be sent at a time. messageType 255 is reserved for internal use and should not be used.


void setUdpRequestHandler(boost::function<void (uint16_t, DUdpModule*&)> udpRequestHandler)

Specify an event handler to call when the remote host requests UDP. The udpRequestHandler will receive a port number and a null-pointer to a DUdpModule. To enable UDP, set the DUdpModule pointer to a module that is bound to the requested port. To refuse the request, leave the pointer set to NULL.

If you accept the request, you will be able to call sendUdp immediately after the udpRequestHandler finishes execution.


bool udpEnabled(void)

Returns true if we can currently send and receive UDP messages from the remote host.





















Back to class reference