RabbitMQ Backend
NSB supports RabbitMQ as an alternative transport backend to raw TCP sockets. This page covers the architecture, Python usage, C++ usage, configuration, and testing of the RabbitMQ implementation.
Overviewโ
In the socket backend, the NSB Daemon acts as a central message router. In the RabbitMQ backend, the RabbitMQ broker handles all message routing natively, reducing the daemon's role to configuration distribution only.
This brings several advantages:
- Better horizontal scalability for large simulations
- Native message persistence, delivery acknowledgments, and queue durability
- Broker-native routing without daemon bottleneck
- Foundation for advanced messaging patterns (priority queues, dead letter exchanges, multicast)
Architectureโ
Componentsโ
| Component | File | Description |
|---|---|---|
RabbitMQInterface | nsb_rabbitmq.py | Low-level AMQP transport; manages connections, channels, queues |
NSBAppClient (RMQ) | nsb_rabbitmq.py | Application client using RabbitMQ transport |
NSBSimClient (RMQ) | nsb_rabbitmq.py | Simulator client using RabbitMQ transport |
NSBDaemon (RMQ) | nsb_daemon.py | Configuration-only daemon service |
NSBUnified | nsb_unified.py | Drop-in unified client supporting both backends |
Queue Naming Conventionโ
All queues follow a consistent naming scheme:
nsb.{channel}.{client_id}
โโโ nsb.ctrl.{client_id} # Control: PING, EXIT
โโโ nsb.send.{client_id} # Outgoing payloads (for sim clients to fetch)
โโโ nsb.recv.{client_id} # Incoming payloads (for app clients to receive)
โโโ nsb.config.request # Daemon initialization queue
โโโ nsb.config.response.{client_id} # Client-specific config response
Message Flowโ
Client Initialization:
Client โ INIT โ nsb.config.request
Daemon โ Config โ nsb.config.response.{client_id}
Client โ receives config, is ready
Application Client Sends:
App.send("dest_id", payload)
โ Published with routing_key = nsb.recv.{dest_id}
โ RabbitMQ routes to dest's RECV queue
โ No daemon involvement
Application Client Receives:
App.receive()
โ Consumes from nsb.recv.{client_id}
โ Returns MessageEntry or None on timeout
Simulator Client Fetches:
Sim.fetch()
โ Consumes from nsb.recv.{sim_id} (SEND messages routed here)
โ Returns MessageEntry
Simulator Client Posts:
Sim.post(src_id, dest_id, payload)
โ Published with routing_key = nsb.recv.{dest_id}
โ App client's RECV queue receives it