OpenServiceBus.Core 1.0.4

dotnet add package OpenServiceBus.Core --version 1.0.4
                    
NuGet\Install-Package OpenServiceBus.Core -Version 1.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OpenServiceBus.Core" Version="1.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OpenServiceBus.Core" Version="1.0.4" />
                    
Directory.Packages.props
<PackageReference Include="OpenServiceBus.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OpenServiceBus.Core --version 1.0.4
                    
#r "nuget: OpenServiceBus.Core, 1.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OpenServiceBus.Core@1.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OpenServiceBus.Core&version=1.0.4
                    
Install as a Cake Addin
#tool nuget:?package=OpenServiceBus.Core&version=1.0.4
                    
Install as a Cake Tool

OpenServiceBus

CI NuGet Docker Hub License: MIT

A zero-dependency, embeddable Azure Service Bus emulator for .NET. Speaks real AMQP 1.0 over TCP and WebSocket so Azure.Messaging.ServiceBus, Azure Functions ServiceBusTrigger, and any other Service Bus client connect unmodified.


Why this exists

Microsoft ships an official Service Bus emulator, but it needs Docker + SQL Server and is EULA-gated. OpenServiceBus is the MIT-licensed alternative: a single-node Service Bus emulator that runs as a NuGet inside your test fixture, as a docker run, or as a standalone executable - no SQL Server, no licensing dance, no 5-minute container boot.

It implements the full Service Bus feature surface that real client code uses: queues, topics + subscriptions (SQL/correlation filters), sessions, duplicate detection, auto-forwarding, transactions, defer, scheduled messages, TTL, peek-lock with renewal, dead-letter routing, exposed over both plain AMQP and AMQP-over-WebSocket, with native OpenTelemetry instrumentation throughout.

OpenServiceBus Official Microsoft emulator
License MIT EULA-gated
Embeddable in tests OpenServiceBus.Testing NuGet
Container size ~230 MB Alpine ~2 GB
Persistence In-memory or SQLite (single file) SQL Server (required)
Transports AMQP-TCP + AMQP-over-WebSocket AMQP-TCP only
Telemetry Native OpenTelemetry tracing + metrics None
config.json compatible

Install

From source

git clone https://github.com/mauritsarissen/OpenServiceBus
cd OpenServiceBus
dotnet run --project src/OpenServiceBus.Host

The host binds amqp://localhost:5672 (Service Bus SDK) and http://localhost:5300 (REST management + /health).

Docker

docker run -d --name openservicebus \
  -p 5672:5672 \
  -p 5300:5300 \
  -p 5400:5400 \
  -v osb-data:/data \
  mauritsarissen/openservicebus:latest
Port What
5672 AMQP (use this in the Azure SDK connection string)
5300 REST management API + /health
5400 Explorer browser UI - open http://localhost:5400
5673 AMQP-over-WebSocket (when OPENSERVICEBUS__WEBSOCKETS__ENABLED=true)

The image runs the broker and the Explorer UI side-by-side. SQLite-backed at /data/broker.db - mount the named volume and queues + messages survive container recreates. See Docker for the compose recipe, every env var, and the WebSocket-transport setup.

Connect

The same connection string works against either install path:

Endpoint=sb://localhost:5672;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true
await using var client = new ServiceBusClient(
    "Endpoint=sb://localhost:5672;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true");

await client.CreateSender("orders").SendMessageAsync(new ServiceBusMessage("hello"));
var msg = await client.CreateReceiver("orders").ReceiveMessageAsync();

UseDevelopmentEmulator=true tells the Azure SDK to skip TLS and accept the broker on plain TCP - the same trick the official Microsoft emulator uses.


As a NuGet inside your tests

If you don't want any external process at all, install the test fixture and run the broker inside your test process:

dotnet add package OpenServiceBus.Testing

Published on nuget.org - no extra source needed. (GitHub Packages also mirrors every release, see Contributing.)

await using var host = await OpenServiceBusTestHost.StartAsync();
await host.CreateQueueAsync("orders");

await using var client = new ServiceBusClient(host.ConnectionString);
await client.CreateSender("orders").SendMessageAsync(new ServiceBusMessage("hello"));

var receiver = client.CreateReceiver("orders");
var msg = await receiver.ReceiveMessageAsync();
await receiver.CompleteMessageAsync(msg);

One disposable host, free ephemeral port, full AMQP semantics - run thousands of these in parallel. See Testing for time-travel, parity testing, and the options surface.


Feature recipes

Topics + filters (SQL / correlation / true / false)

await host.Topics.CreateTopicAsync(new TopicDescriptor { Name = "events" });
await host.Topics.CreateSubscriptionAsync(new SubscriptionDescriptor
    { TopicName = "events", Name = "eu" });
await host.Topics.CreateOrReplaceRuleAsync(new RuleDescriptor
{
    TopicName = "events", SubscriptionName = "eu", Name = "EuOnly",
    Filter = new SqlFilter("region = 'eu' AND priority >= 5"),
});

await client.CreateSender("events").SendMessageAsync(new ServiceBusMessage("hi-eu")
{
    ApplicationProperties = { ["region"] = "eu", ["priority"] = 7 }
});

Topics and Subscriptions

Sessions

await host.Queues.CreateAsync(new QueueDescriptor { Name = "sessioned", RequiresSession = true });
var sender = client.CreateSender("sessioned");
await sender.SendMessageAsync(new ServiceBusMessage("a") { SessionId = "S" });
await sender.SendMessageAsync(new ServiceBusMessage("b") { SessionId = "S" });

var session = await client.AcceptSessionAsync("sessioned", "S");
var first  = await session.ReceiveMessageAsync(); // "a"
var second = await session.ReceiveMessageAsync(); // "b"

Sessions

Transactions (TransactionScope)

using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    await sender.SendMessageAsync(new ServiceBusMessage("a"));
    await receiver.CompleteMessageAsync(previouslyReceivedMessage);
    scope.Complete(); // commit; without this everything rolls back
}

Transactions

Auto-forwarding

await host.Queues.CreateAsync(new QueueDescriptor { Name = "downstream" });
await host.Queues.CreateAsync(new QueueDescriptor
    { Name = "ingress", ForwardTo = "downstream" });
// Sends to "ingress" land on "downstream" - invisible to senders.

Auto-Forwarding

Duplicate detection

await host.Queues.CreateAsync(new QueueDescriptor
{
    Name = "deduped",
    RequiresDuplicateDetection = true,
    DuplicateDetectionHistoryTimeWindow = TimeSpan.FromMinutes(5),
});

await sender.SendMessageAsync(new ServiceBusMessage("first")  { MessageId = "k" });
await sender.SendMessageAsync(new ServiceBusMessage("second") { MessageId = "k" }); // silently dropped

Duplicate Detection

Declarative config.json bootstrap

OpenServiceBus reads the same config.json format as the official Microsoft emulator:

{
  "UserConfig": {
    "Namespaces": [
      {
        "Name": "demo",
        "Queues": [
          {
            "Name": "orders",
            "Properties": {
              "LockDuration": "PT1M",
              "MaxDeliveryCount": 3,
              "RequiresSession": false,
              "DefaultMessageTimeToLive": "PT1H"
            }
          }
        ]
      }
    ]
  }
}

Resolution: --config <path>OPENSERVICEBUS_CONFIG env var → config.json in the host's content-root. Full schema in Configuration.

Persistence (SQLite)

export OPENSERVICEBUS__STORAGE__MODE=Sqlite
export OPENSERVICEBUS__STORAGE__DATASOURCE=/data/broker.db
dotnet run --project src/OpenServiceBus.Host

Persistence

AMQP-over-WebSocket

export OPENSERVICEBUS__WEBSOCKETS__ENABLED=true
dotnet run --project src/OpenServiceBus.Host
await using var client = new ServiceBusClient(
    "Endpoint=sb://localhost:5673;...;UseDevelopmentEmulator=true",
    new ServiceBusClientOptions { TransportType = ServiceBusTransportType.AmqpWebSockets });

WebSocket Transport

OpenTelemetry

services.AddOpenTelemetry()
    .WithTracing(b => b.AddSource(OpenServiceBusDiagnostics.SourceName).AddOtlpExporter())
    .WithMetrics(b => b.AddMeter(OpenServiceBusDiagnostics.SourceName).AddOtlpExporter());

OpenTelemetry


Configuration

The host honors these appsettings.json / environment variable keys:

Key Default Notes
OpenServiceBus:Amqp:Port 5672 AMQP listener port
OpenServiceBus:Amqp:RequireSasAuth false Validate $cbs put-token against SasKeys
OpenServiceBus:Storage:Mode InMemory Sqlite to persist via the SQLite store
OpenServiceBus:Storage:DataSource :memory: Path to the SQLite .db file (use /data/broker.db in containers)
OpenServiceBus:WebSockets:Enabled false Start the AMQP-over-WebSocket bridge
OpenServiceBus:WebSockets:Port 5673 WebSocket bridge port
OPENSERVICEBUS_CONFIG - Path to a config.json for declarative bootstrap

Full reference: Configuration.


Samples

Each sample is self-contained: it ships a docker-compose.yml, a config.json, and a README.md that explains what it demonstrates and how to run it.

See samples/README.md for the full index and a quick chooser table.


Documentation

Multi-page guides in docs/ - also published to the GitHub Wiki:


Development

dotnet build         # multi-targets net8.0 + net10.0
dotnet test          # full regression suite (~210 tests)
docker build -t openservicebus:dev .

The Azure Functions integration test requires func (Azure Functions Core Tools v4) and the .NET 8 runtime; it skips when either is missing. See Contributing for repo conventions, the release flow, and how to add a new milestone.


License

MIT © Maurits Arissen and OpenServiceBus contributors.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on OpenServiceBus.Core:

Package Downloads
OpenServiceBus.Amqp

AMQP 1.0 listener and Service Bus protocol mapping for OpenServiceBus. Built on AMQPNetLite.

OpenServiceBus.InMemoryStorage

In-memory broker implementation: InMemoryMessageStore, QueueManager, LockManager.

OpenServiceBus.Management

Minimal-API REST surface for entity CRUD (queues, topics, subscriptions).

OpenServiceBus.SqliteStorage

SQLite-backed IMessageStore for OpenServiceBus. Persists across restarts; supports both file paths and :memory: for tests.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.4 182 5/20/2026
1.0.3 192 5/20/2026
1.0.2 186 5/19/2026
1.0.1 185 5/19/2026
1.0.0 184 5/19/2026