KubeMQ
LearnEventsTutorials

Multicast Events

Publish events to multiple channels simultaneously using KubeMQ channel routing syntax.

What You Will Build

An order processing system where a single publish call routes to multiple channels — and even multiple messaging patterns — in one operation.

One publish call routes through the KubeMQ router and fans out to Events, Events Store, and Queues channels simultaneously.

Prerequisites

Routing Syntax

CharacterPurposeExample
;Separate multiple channels of the same typeorders;notifications sends to both channels
:Specify the target pattern typeevents:orders;events_store:audit-log

Channel Type Prefixes

PrefixPattern
events:Events (fire-and-forget)
events_store:Events Store (persistent)
queues:Queues (guaranteed delivery)

When no prefix is provided, the channel uses the same pattern as the original publish call.

Steps

Multicast to Same-Pattern Channels

Publish one event to multiple Events channels using the ; separator.

same_pattern_multicast.go
package main

import (
    "context"
    "log"

    "github.com/kubemq-io/kubemq-go/v2"
)

func main() {
    ctx := context.Background()
    client, err := kubemq.NewClient(ctx,
        kubemq.WithAddress("localhost", 50000),
    )
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    err = client.SendEvent(ctx, kubemq.NewEvent().
        SetChannel("orders;notifications").
        SetBody([]byte(`{"orderId":"ORD-500","status":"created"}`)),
    )
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Multicast event sent to orders and notifications")
}
same_pattern_multicast.py
from kubemq.pubsub import Client as PubSubClient
from kubemq.pubsub import EventMessage

client = PubSubClient(address="localhost:50000")
client.send_event(
    EventMessage(
        channel="orders;notifications",
        body=b'{"orderId":"ORD-500","status":"created"}',
    )
)
print("Multicast event sent to orders and notifications")
client.close()
same_pattern_multicast.js
const { KubeMQClient } = require("kubemq-js");

const client = new KubeMQClient({ address: "localhost:50000" });

await client.sendEvent({
  channel: "orders;notifications",
  body: Buffer.from('{"orderId":"ORD-500","status":"created"}'),
});

console.log("Multicast event sent to orders and notifications");
SamePatternMulticast.java
PubSubClient client = PubSubClient.builder()
    .address("localhost:50000")
    .clientId("multicast-publisher")
    .build();

client.sendEventsMessage(EventMessage.builder()
    .channel("orders;notifications")
    .body("{\"orderId\":\"ORD-500\",\"status\":\"created\"}".getBytes())
    .build());

System.out.println("Multicast event sent to orders and notifications");
client.close();
SamePatternMulticast.cs
await using var client = new KubeMQClient(new KubeMQClientOptions());
await client.ConnectAsync();

await client.SendEventAsync(new EventMessage
{
    Channel = "orders;notifications",
    Body = Encoding.UTF8.GetBytes("{\"orderId\":\"ORD-500\",\"status\":\"created\"}")
});

Console.WriteLine("Multicast event sent to orders and notifications");
SamePatternMulticast.kt
val client = PubSubClient("localhost:50000")

client.sendEvent(EventMessage(
    channel = "orders;notifications",
    body = """{"orderId":"ORD-500","status":"created"}""".toByteArray()
))

println("Multicast event sent to orders and notifications")
client.close()
same_pattern_multicast.cpp
auto client = kubemq::PubSubClient("localhost:50000");

kubemq::EventMessage event;
event.channel = "orders;notifications";
event.body = R"({"orderId":"ORD-500","status":"created"})";

client.sendEvent(event);
std::cout << "Multicast event sent to orders and notifications" << std::endl;
same_pattern_multicast.rs
use kubemq::prelude::*;
use kubemq::EventBuilder;

#[tokio::main]
async fn main() -> kubemq::Result<()> {
    let client = KubemqClient::builder()
        .host("localhost")
        .port(50000)
        .build()
        .await?;

    let event = EventBuilder::new()
        .channel("orders;notifications")
        .body(b"{\"orderId\":\"ORD-500\",\"status\":\"created\"}".to_vec())
        .build();

    client.send_event(event).await?;
    println!("Multicast event sent to orders and notifications");

    client.close().await?;
    Ok(())
}
same_pattern_multicast.rb
require 'kubemq'

client = KubeMQ::PubSubClient.new(address: 'localhost:50000', client_id: 'multicast-publisher')

msg = KubeMQ::PubSub::EventMessage.new(
  channel: 'orders;notifications',
  body: '{"orderId":"ORD-500","status":"created"}'
)
client.send_event(msg)

puts 'Multicast event sent to orders and notifications'
client.close
same_pattern_multicast.exs
{:ok, client} = KubeMQ.Client.start_link(address: "localhost:50000", client_id: "multicast-publisher")

event = KubeMQ.Event.new(
  channel: "orders;notifications",
  body: ~s({"orderId":"ORD-500","status":"created"})
)

:ok = KubeMQ.Client.send_event(client, event)
IO.puts("Multicast event sent to orders and notifications")

KubeMQ.Client.close(client)

Multicast Across Different Patterns

Use the : prefix to route one publish to Events, Events Store, and Queues simultaneously.

cross_pattern_multicast.go
err = client.SendEvent(ctx, kubemq.NewEvent().
    SetChannel("events:orders;events_store:audit-log;queues:shipping-tasks").
    SetBody([]byte(`{"orderId":"ORD-600","action":"ship"}`)),
)
if err != nil {
    log.Fatal(err)
}
log.Println("Cross-pattern multicast: events, events_store, queues")
cross_pattern_multicast.py
client.send_event(
    EventMessage(
        channel="events:orders;events_store:audit-log;queues:shipping-tasks",
        body=b'{"orderId":"ORD-600","action":"ship"}',
    )
)
print("Cross-pattern multicast: events, events_store, queues")
cross_pattern_multicast.js
await client.sendEvent({
  channel: "events:orders;events_store:audit-log;queues:shipping-tasks",
  body: Buffer.from('{"orderId":"ORD-600","action":"ship"}'),
});

console.log("Cross-pattern multicast: events, events_store, queues");
CrossPatternMulticast.java
client.sendEventsMessage(EventMessage.builder()
    .channel("events:orders;events_store:audit-log;queues:shipping-tasks")
    .body("{\"orderId\":\"ORD-600\",\"action\":\"ship\"}".getBytes())
    .build());

System.out.println("Cross-pattern multicast: events, events_store, queues");
CrossPatternMulticast.cs
await client.SendEventAsync(new EventMessage
{
    Channel = "events:orders;events_store:audit-log;queues:shipping-tasks",
    Body = Encoding.UTF8.GetBytes("{\"orderId\":\"ORD-600\",\"action\":\"ship\"}")
});

Console.WriteLine("Cross-pattern multicast: events, events_store, queues");
CrossPatternMulticast.kt
client.sendEvent(EventMessage(
    channel = "events:orders;events_store:audit-log;queues:shipping-tasks",
    body = """{"orderId":"ORD-600","action":"ship"}""".toByteArray()
))

println("Cross-pattern multicast: events, events_store, queues")
cross_pattern_multicast.cpp
kubemq::EventMessage event;
event.channel = "events:orders;events_store:audit-log;queues:shipping-tasks";
event.body = R"({"orderId":"ORD-600","action":"ship"})";

client.sendEvent(event);
std::cout << "Cross-pattern multicast: events, events_store, queues" << std::endl;
cross_pattern_multicast.rs
let event = EventBuilder::new()
    .channel("events:orders;events_store:audit-log;queues:shipping-tasks")
    .body(b"{\"orderId\":\"ORD-600\",\"action\":\"ship\"}".to_vec())
    .build();

client.send_event(event).await?;
println!("Cross-pattern multicast: events, events_store, queues");
cross_pattern_multicast.rb
msg = KubeMQ::PubSub::EventMessage.new(
  channel: 'events:orders;events_store:audit-log;queues:shipping-tasks',
  body: '{"orderId":"ORD-600","action":"ship"}'
)
client.send_event(msg)

puts 'Cross-pattern multicast: events, events_store, queues'
cross_pattern_multicast.exs
event = KubeMQ.Event.new(
  channel: "events:orders;events_store:audit-log;queues:shipping-tasks",
  body: ~s({"orderId":"ORD-600","action":"ship"})
)

:ok = KubeMQ.Client.send_event(client, event)
IO.puts("Cross-pattern multicast: events, events_store, queues")

Verify Delivery

Set up subscribers on each target channel. The multicast message arrives at all destinations.

Expected output:

[Events] orders: {"orderId":"ORD-600","action":"ship"}
[Events Store] audit-log: {"orderId":"ORD-600","action":"ship"}
[Queue] shipping-tasks: {"orderId":"ORD-600","action":"ship"}

How Multicast Works Internally

  1. KubeMQ parses the channel string into a route map keyed by pattern type
  2. Sends the first destination synchronously and returns its result to the caller
  3. Fans out remaining destinations asynchronously in background goroutines
  4. Routed messages are tagged with X-KUBEMQ-ROUTED=true automatically

Only the first destination's result is returned to the publisher. Errors on other destinations are logged server-side but do not affect the publish response.

Common Multicast Patterns

Channel StringBehavior
a;b;cSend as Events to channels a, b, and c
events:a;events_store:bSend as Event to a and as persistent Event Store to b
events:a;queues:task-queueBroadcast event and queue a task simultaneously
events_store:audit;queues:process;events:notifyFan out to all three patterns

Next Steps

Was this page helpful?

On this page