304 lines
6.5 KiB
Markdown
304 lines
6.5 KiB
Markdown
# NATSBridge Tutorial
|
|
|
|
A step-by-step guide to get started with NATSBridge - a high-performance, bi-directional data bridge for **Julia**.
|
|
|
|
## Table of Contents
|
|
|
|
1. [Overview](#overview)
|
|
2. [Prerequisites](#prerequisites)
|
|
3. [Installation](#installation)
|
|
4. [Quick Start](#quick-start)
|
|
5. [Basic Examples](#basic-examples)
|
|
6. [Advanced Usage](#advanced-usage)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
NATSBridge enables seamless communication for Julia applications through NATS, with automatic transport selection based on payload size:
|
|
|
|
- **Direct Transport**: Payloads < 1MB are sent directly via NATS (Base64 encoded)
|
|
- **Link Transport**: Payloads >= 1MB are uploaded to an HTTP file server and referenced via URL
|
|
|
|
### Supported Payload Types
|
|
|
|
| Type | Description |
|
|
|------|-------------|
|
|
| `text` | Plain text strings |
|
|
| `dictionary` | JSON-serializable dictionaries |
|
|
| `table` | Tabular data (Arrow IPC format) |
|
|
| `image` | Image data (PNG, JPG bytes) |
|
|
| `audio` | Audio data (WAV, MP3 bytes) |
|
|
| `video` | Video data (MP4, AVI bytes) |
|
|
| `binary` | Generic binary data |
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
Before you begin, ensure you have:
|
|
|
|
1. **NATS Server** running (or accessible)
|
|
2. **HTTP File Server** (optional, for large payloads > 1MB)
|
|
3. **Julia** with required packages
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
### Julia
|
|
|
|
```julia
|
|
using Pkg
|
|
Pkg.add("NATS")
|
|
Pkg.add("Arrow")
|
|
Pkg.add("JSON3")
|
|
Pkg.add("HTTP")
|
|
Pkg.add("UUIDs")
|
|
Pkg.add("Dates")
|
|
```
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### Step 1: Start NATS Server
|
|
|
|
```bash
|
|
docker run -p 4222:4222 nats:latest
|
|
```
|
|
|
|
### Step 2: Start HTTP File Server (Optional)
|
|
|
|
```bash
|
|
# Create a directory for file uploads
|
|
mkdir -p /tmp/fileserver
|
|
|
|
# Use any HTTP server that supports POST for file uploads
|
|
python3 -m http.server 8080 --directory /tmp/fileserver
|
|
```
|
|
|
|
### Step 3: Send Your First Message
|
|
|
|
#### Julia
|
|
|
|
```julia
|
|
using NATSBridge
|
|
|
|
# Send a text message
|
|
data = [("message", "Hello World", "text")]
|
|
env, env_json_str = smartsend("/chat/room1", data, broker_url="nats://localhost:4222")
|
|
# env: msg_envelope_v1 object with all metadata and payloads
|
|
# env_json_str: JSON string representation of the envelope for publishing
|
|
println("Message sent!")
|
|
|
|
# Or use is_publish=false to get envelope and JSON without publishing
|
|
env, env_json_str = smartsend("/chat/room1", data, broker_url="nats://localhost:4222", is_publish=false)
|
|
# env: msg_envelope_v1 object
|
|
# env_json_str: JSON string for publishing to NATS
|
|
```
|
|
|
|
### Step 4: Receive Messages
|
|
|
|
#### Julia
|
|
|
|
```julia
|
|
using NATSBridge
|
|
|
|
# Receive and process message
|
|
env = smartreceive(msg; fileserver_download_handler=_fetch_with_backoff)
|
|
for (dataname, data, type) in env["payloads"]
|
|
println("Received $dataname: $data")
|
|
end
|
|
```
|
|
|
|
---
|
|
|
|
## Basic Examples
|
|
|
|
### Example 1: Sending a Dictionary
|
|
|
|
#### Julia
|
|
|
|
```julia
|
|
using NATSBridge
|
|
|
|
config = Dict(
|
|
"wifi_ssid" => "MyNetwork",
|
|
"wifi_password" => "password123",
|
|
"update_interval" => 60
|
|
)
|
|
|
|
data = [("config", config, "dictionary")]
|
|
env, env_json_str = smartsend("/device/config", data, broker_url="nats://localhost:4222")
|
|
```
|
|
|
|
### Example 2: Sending Binary Data (Image)
|
|
|
|
#### Julia
|
|
|
|
```julia
|
|
using NATSBridge
|
|
|
|
# Read image file
|
|
image_data = read("image.png")
|
|
|
|
data = [("user_image", image_data, "binary")]
|
|
env, env_json_str = smartsend("/chat/image", data, broker_url="nats://localhost:4222")
|
|
```
|
|
|
|
### Example 3: Request-Response Pattern
|
|
|
|
#### Julia (Requester)
|
|
|
|
```julia
|
|
using NATSBridge
|
|
|
|
# Send command with reply-to
|
|
data = [("command", Dict("action" => "read_sensor"), "dictionary")]
|
|
env, env_json_str = smartsend(
|
|
"/device/command",
|
|
data,
|
|
broker_url="nats://localhost:4222",
|
|
reply_to="/device/response",
|
|
reply_to_msg_id="cmd-001"
|
|
)
|
|
# env: msg_envelope_v1 object
|
|
# env_json_str: JSON string for publishing to NATS
|
|
```
|
|
|
|
#### Julia (Responder)
|
|
|
|
```julia
|
|
using NATS, NATSBridge
|
|
|
|
# Configuration
|
|
const SUBJECT = "/device/command"
|
|
const NATS_URL = "nats://localhost:4222"
|
|
|
|
function test_responder()
|
|
conn = NATS.connect(NATS_URL)
|
|
NATS.subscribe(conn, SUBJECT) do msg
|
|
env = smartreceive(msg, fileserver_download_handler=_fetch_with_backoff)
|
|
|
|
# Extract reply_to from the envelope metadata
|
|
reply_to = env["reply_to"]
|
|
|
|
for (dataname, data, type) in env["payloads"]
|
|
if dataname == "command" && data["action"] == "read_sensor"
|
|
response = Dict("sensor_id" => "sensor-001", "value" => 42.5)
|
|
# Send response to the reply_to subject from the request
|
|
if !isempty(reply_to)
|
|
smartsend(reply_to, [("data", response, "dictionary")])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
sleep(120)
|
|
NATS.drain(conn)
|
|
end
|
|
|
|
test_responder()
|
|
```
|
|
|
|
---
|
|
|
|
## Advanced Usage
|
|
|
|
### Example 4: Large Payloads (File Server)
|
|
|
|
For payloads larger than 1MB, NATSBridge automatically uses the file server:
|
|
|
|
#### Julia
|
|
|
|
```julia
|
|
using NATSBridge
|
|
|
|
# Create large data (> 1MB)
|
|
large_data = rand(UInt8, 2_000_000)
|
|
|
|
env, env_json_str = smartsend(
|
|
"/data/large",
|
|
[("large_file", large_data, "binary")],
|
|
broker_url="nats://localhost:4222",
|
|
fileserver_url="http://localhost:8080"
|
|
)
|
|
|
|
# The envelope will contain the download URL
|
|
println("File uploaded to: $(env.payloads[1].data)")
|
|
```
|
|
|
|
### Example 5: Mixed Content (Chat with Text + Image)
|
|
|
|
NATSBridge supports sending multiple payloads with different types in a single message:
|
|
|
|
#### Julia
|
|
|
|
```julia
|
|
using NATSBridge
|
|
|
|
image_data = read("avatar.png")
|
|
|
|
data = [
|
|
("message_text", "Hello with image!", "text"),
|
|
("user_avatar", image_data, "image")
|
|
]
|
|
|
|
env, env_json_str = smartsend("/chat/mixed", data, broker_url="nats://localhost:4222")
|
|
```
|
|
|
|
### Example 6: Table Data (Arrow IPC)
|
|
|
|
For tabular data, NATSBridge uses Apache Arrow IPC format:
|
|
|
|
#### Julia
|
|
|
|
```julia
|
|
using NATSBridge
|
|
using DataFrames
|
|
|
|
# Create DataFrame
|
|
df = DataFrame(
|
|
id = [1, 2, 3],
|
|
name = ["Alice", "Bob", "Charlie"],
|
|
score = [95, 88, 92]
|
|
)
|
|
|
|
data = [("students", df, "table")]
|
|
env, env_json_str = smartsend("/data/students", data, broker_url="nats://localhost:4222")
|
|
```
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. **Explore the test directory** for more examples
|
|
2. **Check the documentation** for advanced configuration options
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Connection Issues
|
|
|
|
- Ensure NATS server is running: `docker ps | grep nats`
|
|
- Check firewall settings
|
|
- Verify NATS URL configuration
|
|
|
|
### File Server Issues
|
|
|
|
- Ensure file server is running and accessible
|
|
- Check upload permissions
|
|
- Verify file server URL configuration
|
|
|
|
### Serialization Errors
|
|
|
|
- Verify data type matches the specified type
|
|
- Check that binary data is in the correct format (Vector{UInt8})
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
MIT |