Routing handlers control how message addresses are handled. For instance, RedMQ currently defines two routing handlers - channel and topic. Internally, the global router uses routing handlers by recognizing the handler type by parsing the address and reading the prefix (before the @). This allows developers to completely customize the way messages travel within RedMQ.
The IRoute interface
:::python
# Similar to command handlers, routing handlers must implement
# the IPlugin and IRoute interfaces and use a decorator to
# register the route.
from zope.interface import implements
from twisted.plugin import IPlugin
from redmq_server import router, IRoute, Channel
Defining the route
Following is the current implementation of the channel router. This demonstrates the relationship between a routing handler, the RedMQ router, and Redis storage.
:::python
# Use the route decorator to register the route.
# Note also that the route's class name is important
# as it is used as the routing identifier in addresses.
@router.route
class myroute:
# Implement IPlugin and IRoute interfaces. The IPlugin interface
# is required for Twisted to recognize this class as a plugin,
# and IRoute is required by RedMQ.
implements(IPlugin, IRoute)
# The single method required by the IRoute interface is route(),
# accepting the full address and message to route to the appropriate
# channels. The return value is a dictionary of lists of channels,
# with each list keyed by the message address. This allows the router
# to facilitate message having different real addresses depending on
# the destination, as in the case of topic routing. See the topic
# routing handler for more information on how this works.
def route(self, address, message):
return {address: [Channel(address, self.redis)]}
# Note that we can also access the router from which this handler
# was called directly as an instance variable. Similarly, we can
# access the global router Redis instance. However, routing handlers
# and the global router are not related to any specific channel or
# protocol instance because the very nature and purpose of the router
# and its handlers is to server as a link between channels.
router = self.router
redis = self.redis
Now that we've registered a new route - myroute
- we can send messages directed at this specific router. For example:
~~~~~~~~~~~~~~~~~~~~
:::python
with client.channel('foo') as channel:
channel.send('Send to myroute routing handler.', 'myroute@bar')
~~~~~~~~~~~~~~~~~