# Wildcard Subscription (/sdks/csharp/how-to/events/wildcard-subscription)



## Overview [#overview]

A **wildcard subscription** lets one subscriber match a whole family of channels with a single call, instead of wiring up a separate `SubscribeToEventsAsync` for every sub-channel and touching code each time a new one appears. It's the natural fit for monitoring, logging, or fan-in aggregation across a channel hierarchy — for example, watching every regional order channel from one place.

KubeMQ matches wildcard tokens against the channel hierarchy server-side at delivery time. `*` matches exactly one dot-separated segment, and `>` matches one or more trailing segments, so an `EventsSubscription { Channel = "csharp-events.wildcard.*" }` catches any single-segment suffix. Every delivered message still carries its exact `Channel`, so the handler can tell which concrete sub-channel it came from even though the subscription itself only named a pattern.

**Gotchas:** `*` matches exactly one segment — it won't reach two levels deep, so `orders.*` misses `orders.us.east`; use `>` for that. Wildcards are only valid on Events subscriptions, not on `SendEventAsync`/publishes or on events-store, queues, or commands/queries. And an overly broad pattern like `>` at the root will quietly pull in every channel under that prefix, including ones you didn't intend to monitor.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* C# SDK installed (`dotnet add package KubeMQ.SDK.CSharp`)

## Code [#code]

```csharp title="Program.cs"
// KubeMQ .NET SDK — Events: Wildcard Subscription
//
// This example demonstrates subscribing to events using a wildcard channel pattern.
// Wildcard subscriptions receive events from all channels matching the pattern.
//
// Prerequisites:
//   - KubeMQ server running on localhost:50000
//   - dotnet run

using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Events;
using System.Text;

await using var client = new KubeMQClient(new KubeMQClientOptions
{
    ClientId = "csharp-events-wildcard-subscription-client",
});
await client.ConnectAsync();

Console.WriteLine("Connected to KubeMQ server");

var cts = new CancellationTokenSource();

// Subscribe to all channels matching "csharp-events.wildcard.*"
var subscribeTask = Task.Run(async () =>
{
    await foreach (var msg in client.SubscribeToEventsAsync(
        new EventsSubscription { Channel = "csharp-events.wildcard.*" }, cts.Token))
    {
        Console.WriteLine($"[{msg.Channel}] {Encoding.UTF8.GetString(msg.Body.Span)}");
    }
});

await Task.Delay(1000);

// Publish to different sub-channels
await client.SendEventAsync(new EventMessage
{
    Channel = "csharp-events.wildcard.created",
    Body = Encoding.UTF8.GetBytes("Order #100 created")
});

await client.SendEventAsync(new EventMessage
{
    Channel = "csharp-events.wildcard.shipped",
    Body = Encoding.UTF8.GetBytes("Order #99 shipped")
});

await client.SendEventAsync(new EventMessage
{
    Channel = "csharp-events.wildcard.cancelled",
    Body = Encoding.UTF8.GetBytes("Order #98 cancelled")
});

await Task.Delay(2000);
cts.Cancel();

Console.WriteLine("Done.");

```

## How It Works [#how-it-works]

* The channel pattern `csharp-events.wildcard.*` uses `*` as a single-level wildcard: it matches any channel name that has exactly one more segment after the dot.
* The broker routes each published event to all subscribers whose channel pattern matches the event's concrete channel name at subscription time.
* `msg.Channel` in the callback carries the actual channel the event was published on, letting you route on the sub-topic inside the handler.
* Use `>` in place of `*` if you need a multi-level wildcard (matches any number of trailing segments).

## Related [#related]

* [Pattern overview](/learn/events/getting-started)
* [C# SDK Reference](/sdks/csharp/reference)
* [Basic Pub/Sub](/sdks/csharp/tutorials/basic-pubsub)
* [Cancel Subscription](/sdks/csharp/how-to/events/cancel-subscription)
