Zcat.Tool
0.0.3
dotnet tool install --global Zcat.Tool --version 0.0.3
dotnet new tool-manifest
dotnet tool install --local Zcat.Tool --version 0.0.3
#tool dotnet:?package=Zcat.Tool&version=0.0.3
nuke :add-package Zcat.Tool --version 0.0.3
zcat - ZeroMQ CLI Tool
A powerful command-line tool for interacting with ZeroMQ messaging patterns. Send and receive messages using PUB/SUB, REQ/REP, PUSH/PULL patterns with timeout support, message limits, and graceful shutdown.
Features
- ✅ Multiple ZeroMQ Patterns: PUB/SUB, REQ/REP, PUSH/PULL
- ⏱️ Timeout Support: Auto-exit after specified seconds
- 🔢 Message Count Limits: Exit after N messages
- 🎯 Topic Filtering: Subscribe to specific topics
- 🔌 Bind or Connect: Choose socket connection mode
- 🛑 Graceful Shutdown: Ctrl+C handling
- 📊 Verbose/Quiet Modes: Control output verbosity
- 🚀 Zero Config: Works out of the box with sensible defaults
Installation
From NuGet (once published)
dotnet tool install --global Zcat.Tool
From Source
git clone https://github.com/cppxaxa/zcat-tool.git
cd zcat-tool
dotnet pack -c Release
dotnet tool install --global --add-source ./bin/Release Zcat.Tool
Usage
Get Help
# Show basic help
zcat --help
# Show quick start guide with all patterns and examples
zcat --quickstart
# or
zcat --examples
Basic Syntax
zcat <command> [address] [options]
Commands
sub- Subscribe to messages (SUB socket)pub- Publish messages (PUB socket)req- Send requests (REQ socket - client)rep- Reply to requests (REP socket - server)push- Push messages to pipeline (PUSH socket)pull- Pull messages from pipeline (PULL socket)
Options
| Flag | Description | Default |
|---|---|---|
-a, --address <addr> |
ZeroMQ address | tcp://localhost:5556 |
-t, --timeout <sec> |
Exit after N seconds | 0 (infinite) |
-c, --count <num> |
Exit after N messages | 0 (unlimited) |
--topic <topic> |
Topic filter (SUB) or prefix (PUB) | "" (all) |
-b, --bind |
Bind socket (server mode) | false |
--connect |
Connect socket (client mode) | true |
-v, --verbose |
Verbose output | false |
-q, --quiet |
Quiet mode (no info logs) | false |
Examples
Quick Test (PUB/SUB)
Important: Start the publisher FIRST with --bind, then start subscriber(s). Wait 1-2 seconds after subscribers connect before sending messages (this avoids the ZeroMQ "slow joiner" problem).
# Terminal 1 - Start publisher (bind first!)
zcat pub tcp://*:5556 --bind
# Terminal 2 - Start subscriber
zcat sub tcp://localhost:5556 --timeout 30
# Terminal 1 - Send messages (wait 1-2 sec after subscriber starts)
# Type messages and press Enter
Hello ZeroMQ!
Testing 123
Publisher/Subscriber Pattern
Terminal 1 - Start publisher (bind):
# Bind and publish
zcat pub tcp://*:5556 --bind
# Publish with topic prefix
zcat pub tcp://*:5556 --bind --topic weather
Terminal 2 - Start subscriber (connect):
# Subscribe to all messages
zcat sub tcp://localhost:5556
# Subscribe with 30 second timeout
zcat sub tcp://localhost:5556 --timeout 30
# Subscribe to specific topic
zcat sub tcp://localhost:5556 --topic weather
# Exit after 100 messages
zcat sub tcp://localhost:5556 --count 100
Request/Reply Pattern
Terminal 1 - Start replier (server):
# Bind and wait for requests
zcat rep tcp://*:5557 --bind
Terminal 2 - Send requests (client):
# Send request and get reply
echo "ping" | zcat req tcp://localhost:5557
Push/Pull Pipeline Pattern
Terminal 1 - Start pullers (workers):
# Worker 1
zcat pull tcp://localhost:5558
# Worker 2 (in another terminal)
zcat pull tcp://localhost:5558
Terminal 2 - Start pusher:
# Push work to workers (they'll load balance)
zcat push tcp://*:5558 --bind
Common Use Cases
Monitoring Live Messages
# Watch messages for 10 seconds
zcat sub tcp://prod-server:5556 --timeout 10
# Sample 50 messages
zcat sub tcp://prod-server:5556 --count 50
Testing & Debugging
# Test publisher is working
zcat sub tcp://localhost:5556 --timeout 5 --verbose
# Send test message
echo "test message" | zcat pub tcp://localhost:5556
Load Testing
# Generate 1000 messages
seq 1 1000 | zcat push tcp://*:5559 --bind
# Pull and process
zcat pull tcp://localhost:5559 --count 1000
Integration with Unix Tools
# Pipe to grep
zcat sub tcp://logs:5556 | grep ERROR
# Pipe from file
cat messages.txt | zcat pub tcp://*:5556 --bind
# Count messages in 60 seconds
zcat sub tcp://events:5556 --timeout 60 | wc -l
Architecture
Bind vs Connect
- Bind (
--bind): Socket acts as server, waits for connections - Connect (default): Socket acts as client, connects to server
Rule of thumb:
- SUB sockets usually connect to PUB
- PUB sockets usually bind
- REP sockets usually bind (server)
- REQ sockets usually connect (client)
- PULL sockets usually bind
- PUSH sockets usually connect
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success (normal exit or timeout) |
| 1 | Error (connection failed, invalid args, etc.) |
Troubleshooting
"Address already in use"
Multiple processes trying to bind to the same address. Use --connect or choose different port.
# Instead of binding
zcat pub tcp://*:5556 --bind
# Try connecting
zcat pub tcp://localhost:5556
No messages received (PUB/SUB)
This is often due to the ZeroMQ "slow joiner" problem:
- Always start the publisher FIRST with
--bind - Then start subscriber(s) with
--connect(default) - Wait 1-2 seconds after subscribers connect before sending messages
- Verify topic filters match
- Try
--verbosemode to see connection status
# Correct order:
# Terminal 1
zcat pub tcp://*:5556 --bind
# Terminal 2 (wait for publisher to be ready)
zcat sub tcp://localhost:5556
# Terminal 1 (wait 1-2 seconds after subscriber starts, then type)
Hello!
Other checks:
- Check firewall settings
- Ensure addresses match (localhost vs 0.0.0.0 vs *)
Messages not load balancing
In PUSH/PULL, workers must be connected before messages are sent. Add a small delay:
# Start workers first, then:
sleep 1 && cat work.txt | zcat push tcp://*:5559 --bind
Development
Build
dotnet build
Run Locally
dotnet run -- sub tcp://localhost:5556 --timeout 5
Test
# Terminal 1
dotnet run -- sub tcp://localhost:5556
# Terminal 2
echo "test" | dotnet run -- pub tcp://localhost:5556
License
MIT
Contributing
Pull requests welcome! Please ensure:
- Code follows existing style
- Add tests for new features
- Update documentation
Links
| Product | Versions 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 was computed. 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. |
This package has no dependencies.