Message Routing

TODO -- talk about messaging Uri

TIP

Some of the transports have conventional routing approaches as well as the explicit routing rules shown in this page.

When you publish a message using IMessagePublisher or IExecutionContext without explicitly setting the Uri of the desired destination, Jasper has to invoke the known message routing rules and dynamic subscriptions to figure out which locations should receive the message. Consider this code that publishes a PingMessage:

public class SendingExample
{
    public async Task SendPingsAndPongs(IExecutionContext bus)
    {
        // Publish a message
        await bus.SendAsync(new PingMessage());
    }
}

snippet source | anchor

To route messages to specific endpoints, we can apply static message routing rules by using a routing rule as shown below:

using var host = Host.CreateDefaultBuilder()
    .UseJasper(opts =>
    {
        // Route a single message type
        opts.PublishMessage<PingMessage>()
            .ToServerAndPort("server", 1111);

        // Send every possible message to a TCP listener
        // on this box at port 2222
        opts.PublishAllMessages().ToPort(2222);

        // Or use a more fluent interface style
        opts.Publish().MessagesFromAssembly(typeof(PingMessage).Assembly)
            .ToPort(3333);

        // Complicated rules, I don't think folks will use this much
        opts.Publish(rule =>
        {
            // Apply as many message matching
            // rules as you need

            // Specific message types
            rule.Message<PingMessage>();
            rule.Message<Message1>();

            // All types in a certain assembly
            rule.MessagesFromAssemblyContaining<PingMessage>();

            // or this
            rule.MessagesFromAssembly(typeof(PingMessage).Assembly);

            // or by namespace
            rule.MessagesFromNamespace("MyMessageLibrary");
            rule.MessagesFromNamespaceContaining<PingMessage>();

            // Express the subscribers
            rule.ToPort(1111);
            rule.ToPort(2222);
        });

        // Or you just send all messages to a certain endpoint
        opts.PublishAllMessages().ToPort(3333);
    }).StartAsync();

snippet source | anchor

Do note that doing the message type filtering by namespace will also include child namespaces. In our own usage we try to rely on either namespace rules or by using shared message assemblies.