update
This commit is contained in:
552
README.md
552
README.md
@@ -1,6 +1,6 @@
|
||||
# NATSBridge
|
||||
|
||||
A high-performance, bi-directional data bridge between **Julia**, **JavaScript**, and **Python/Micropython** applications using NATS (Core & JetStream), implementing the Claim-Check pattern for large payloads.
|
||||
A high-performance, bi-directional data bridge for **Julia** applications using NATS (Core & JetStream), implementing the Claim-Check pattern for large payloads.
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://nats.io)
|
||||
@@ -25,7 +25,7 @@ A high-performance, bi-directional data bridge between **Julia**, **JavaScript**
|
||||
|
||||
## Overview
|
||||
|
||||
NATSBridge enables seamless communication across Julia, JavaScript, and Python/Micropython applications through NATS, with intelligent transport selection based on payload size:
|
||||
NATSBridge enables seamless communication for Julia applications through NATS, with intelligent transport selection based on payload size:
|
||||
|
||||
| Transport | Payload Size | Method |
|
||||
|-----------|--------------|--------|
|
||||
@@ -37,14 +37,13 @@ NATSBridge enables seamless communication across Julia, JavaScript, and Python/M
|
||||
- **Chat Applications**: Text, images, audio, video in a single message
|
||||
- **File Transfer**: Efficient transfer of large files using claim-check pattern
|
||||
- **Streaming Data**: Sensor data, telemetry, and analytics pipelines
|
||||
- **Cross-Platform Communication**: Julia ↔ JavaScript ↔ Python/Micropython
|
||||
- **IoT Devices**: Micropython devices sending data to cloud services
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ **Bi-directional messaging** between Julia, JavaScript, and Python/Micropython
|
||||
- ✅ **Bi-directional messaging** for Julia applications
|
||||
- ✅ **Multi-payload support** - send multiple payloads with different types in one message
|
||||
- ✅ **Automatic transport selection** - direct vs link based on payload size
|
||||
- ✅ **Claim-Check pattern** for payloads > 1MB
|
||||
@@ -53,7 +52,7 @@ NATSBridge enables seamless communication across Julia, JavaScript, and Python/M
|
||||
- ✅ **Correlation ID tracking** for message tracing
|
||||
- ✅ **Reply-to support** for request-response patterns
|
||||
- ✅ **JetStream support** for message replay and durability
|
||||
- ✅ **Lightweight Micropython implementation** for microcontrollers
|
||||
|
||||
|
||||
---
|
||||
|
||||
@@ -65,16 +64,12 @@ NATSBridge enables seamless communication across Julia, JavaScript, and Python/M
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ NATSBridge Architecture │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Julia │ │ JavaScript │ │ Python/ │ │
|
||||
│ │ (NATS.jl) │◄──►│ (nats.js) │◄──►│ Micropython │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ NATS │ │
|
||||
│ │ (Message Broker) │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────┐ │ │
|
||||
│ │ Julia │ ▼ │
|
||||
│ │ (NATS.jl) │ ┌─────────────────────────┐ │
|
||||
│ └──────────────┘ │ NATS │ │
|
||||
│ │ (Message Broker) │ │
|
||||
│ └─────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────────┐ │
|
||||
@@ -110,40 +105,6 @@ Pkg.add("NATS")
|
||||
Pkg.add("https://git.yiem.cc/ton/NATSBridge")
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
||||
```bash
|
||||
npm install nats.js apache-arrow uuid base64-url
|
||||
```
|
||||
|
||||
For Node.js:
|
||||
```javascript
|
||||
const { smartsend, smartreceive } = require('./src/NATSBridge');
|
||||
```
|
||||
|
||||
For browser:
|
||||
```html
|
||||
<script src="./src/NATSBridge.js"></script>
|
||||
<script>
|
||||
// NATSBridge is available as window.NATSBridge
|
||||
</script>
|
||||
```
|
||||
|
||||
### Python/Micropython
|
||||
|
||||
1. Copy [`src/nats_bridge.py`](src/nats_bridge.py) to your device
|
||||
2. Install dependencies:
|
||||
|
||||
**For Python (desktop):**
|
||||
```bash
|
||||
pip install nats-py
|
||||
```
|
||||
|
||||
**For Micropython:**
|
||||
- `urequests` for HTTP requests (built-in for ESP32)
|
||||
- `base64` for base64 encoding (built-in)
|
||||
- `json` for JSON handling (built-in)
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
@@ -160,36 +121,12 @@ docker run -p 4222:4222 nats:latest
|
||||
# Create a directory for file uploads
|
||||
mkdir -p /tmp/fileserver
|
||||
|
||||
# Use Python's built-in server
|
||||
# Start HTTP file server
|
||||
python3 -m http.server 8080 --directory /tmp/fileserver
|
||||
```
|
||||
|
||||
### Step 3: Send Your First Message
|
||||
|
||||
#### Python/Micropython
|
||||
|
||||
```python
|
||||
from nats_bridge import smartsend
|
||||
|
||||
# Send a text message
|
||||
data = [("message", "Hello World", "text")]
|
||||
env, env_json_str = smartsend("/chat/room1", data, broker_url="nats://localhost:4222")
|
||||
print("Message sent!")
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
|
||||
```javascript
|
||||
const { smartsend } = require('./src/NATSBridge');
|
||||
|
||||
// Send a text message
|
||||
const { env, env_json_str } = await smartsend("/chat/room1", [
|
||||
{ dataname: "message", data: "Hello World", type: "text" }
|
||||
], { broker_url: "nats://localhost:4222" });
|
||||
|
||||
console.log("Message sent!");
|
||||
```
|
||||
|
||||
#### Julia
|
||||
|
||||
```julia
|
||||
@@ -203,64 +140,6 @@ println("Message sent!")
|
||||
|
||||
### Step 4: Receive Messages
|
||||
|
||||
#### Python/Micropython
|
||||
|
||||
```python
|
||||
import nats
|
||||
import asyncio
|
||||
from nats_bridge import smartreceive
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/chat/room1"
|
||||
NATS_URL = "nats://localhost:4222"
|
||||
|
||||
async def main():
|
||||
# Connect to NATS
|
||||
nc = await nats.connect(NATS_URL)
|
||||
|
||||
# Subscribe to the subject - msg comes from the callback
|
||||
async def message_handler(msg):
|
||||
# Receive and process message
|
||||
env = smartreceive(msg.data)
|
||||
for dataname, data, type in env["payloads"]:
|
||||
print(f"Received {dataname}: {data}")
|
||||
|
||||
sid = await nc.subscribe(SUBJECT, cb=message_handler)
|
||||
await asyncio.sleep(120) # Keep listening
|
||||
await nc.close()
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
|
||||
```javascript
|
||||
const { smartreceive } = require('./src/NATSBridge');
|
||||
const { connect } = require('nats');
|
||||
|
||||
// Configuration
|
||||
const SUBJECT = "/chat/room1";
|
||||
const NATS_URL = "nats://localhost:4222";
|
||||
|
||||
async function main() {
|
||||
// Connect to NATS
|
||||
const nc = await connect({ servers: [NATS_URL] });
|
||||
|
||||
// Subscribe to the subject - msg comes from the async iteration
|
||||
const sub = nc.subscribe(SUBJECT);
|
||||
|
||||
for await (const msg of sub) {
|
||||
// Receive and process message
|
||||
const env = await smartreceive(msg);
|
||||
for (const payload of env.payloads) {
|
||||
console.log(`Received ${payload.dataname}: ${payload.data}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
#### Julia
|
||||
|
||||
```julia
|
||||
@@ -305,54 +184,6 @@ test_receive()
|
||||
|
||||
Sends data either directly via NATS or via a fileserver URL, depending on payload size.
|
||||
|
||||
#### Python/Micropython
|
||||
|
||||
```python
|
||||
from nats_bridge import smartsend
|
||||
|
||||
env, env_json_str = smartsend(
|
||||
subject, # NATS subject to publish to
|
||||
data, # List of (dataname, data, type) tuples
|
||||
broker_url="nats://localhost:4222", # NATS server URL
|
||||
fileserver_url="http://localhost:8080", # File server URL
|
||||
fileserver_upload_handler=plik_oneshot_upload, # Upload handler function
|
||||
size_threshold=1_000_000, # Threshold in bytes (default: 1MB)
|
||||
correlation_id=None, # Optional correlation ID for tracing
|
||||
msg_purpose="chat", # Message purpose
|
||||
sender_name="NATSBridge", # Sender name
|
||||
receiver_name="", # Receiver name (empty = broadcast)
|
||||
receiver_id="", # Receiver UUID (empty = broadcast)
|
||||
reply_to="", # Reply topic
|
||||
reply_to_msg_id="", # Reply message ID
|
||||
is_publish=True # Whether to automatically publish to NATS
|
||||
)
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
|
||||
```javascript
|
||||
const { smartsend } = require('./src/NATSBridge');
|
||||
|
||||
const { env, env_json_str } = await smartsend(
|
||||
subject, // NATS subject
|
||||
data, // Array of {dataname, data, type}
|
||||
{
|
||||
broker_url: "nats://localhost:4222",
|
||||
fileserver_url: "http://localhost:8080",
|
||||
fileserver_upload_handler: customUploadHandler,
|
||||
size_threshold: 1_000_000,
|
||||
correlation_id: "custom-id",
|
||||
msg_purpose: "chat",
|
||||
sender_name: "NATSBridge",
|
||||
receiver_name: "",
|
||||
receiver_id: "",
|
||||
reply_to: "",
|
||||
reply_to_msg_id: "",
|
||||
is_publish: true // Whether to automatically publish to NATS
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
#### Julia
|
||||
|
||||
```julia
|
||||
@@ -384,40 +215,6 @@ env, env_json_str = NATSBridge.smartsend(
|
||||
|
||||
Receives and processes messages from NATS, handling both direct and link transport.
|
||||
|
||||
#### Python/Micropython
|
||||
|
||||
```python
|
||||
from nats_bridge import smartreceive
|
||||
|
||||
# Note: For nats-py, use msg.data to pass the raw message data
|
||||
env = smartreceive(
|
||||
msg.data, # NATS message data (msg.data for nats-py)
|
||||
fileserver_download_handler=_fetch_with_backoff, # Download handler
|
||||
max_retries=5, # Max retry attempts
|
||||
base_delay=100, # Initial delay in ms
|
||||
max_delay=5000 # Max delay in ms
|
||||
)
|
||||
# Returns: Dict with envelope metadata and 'payloads' field
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
|
||||
```javascript
|
||||
const { smartreceive } = require('./src/NATSBridge');
|
||||
|
||||
// Note: msg is the NATS message object from subscription
|
||||
const env = await smartreceive(
|
||||
msg, // NATS message (raw object from subscription)
|
||||
{
|
||||
fileserverDownloadHandler: customDownloadHandler,
|
||||
maxRetries: 5,
|
||||
baseDelay: 100,
|
||||
maxDelay: 5000
|
||||
}
|
||||
);
|
||||
// Returns: Object with envelope metadata and payloads array
|
||||
```
|
||||
|
||||
#### Julia
|
||||
|
||||
```julia
|
||||
@@ -485,19 +282,6 @@ NATSBridge.publish_message(conn, "/chat/room1", "{\"correlation_id\":\"abc123\"}
|
||||
|
||||
Small payloads are sent directly via NATS with Base64 encoding.
|
||||
|
||||
#### Python/Micropython
|
||||
```python
|
||||
data = [("message", "Hello", "text")]
|
||||
smartsend("/topic", data)
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
```javascript
|
||||
await smartsend("/topic", [
|
||||
{ dataname: "message", data: "Hello", type: "text" }
|
||||
]);
|
||||
```
|
||||
|
||||
#### Julia
|
||||
```julia
|
||||
data = [("message", "Hello", "text")]
|
||||
@@ -508,19 +292,6 @@ smartsend("/topic", data)
|
||||
|
||||
Large payloads are uploaded to an HTTP file server.
|
||||
|
||||
#### Python/Micropython
|
||||
```python
|
||||
data = [("file", large_data, "binary")]
|
||||
smartsend("/topic", data, fileserver_url="http://localhost:8080")
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
```javascript
|
||||
await smartsend("/topic", [
|
||||
{ dataname: "file", data: largeData, type: "binary" }
|
||||
], { fileserver_url: "http://localhost:8080" });
|
||||
```
|
||||
|
||||
#### Julia
|
||||
```julia
|
||||
data = [("file", large_data, "binary")]
|
||||
@@ -531,38 +302,10 @@ smartsend("/topic", data; fileserver_url="http://localhost:8080")
|
||||
|
||||
## Examples
|
||||
|
||||
All examples include code for **Julia**, **JavaScript**, and **Python/Micropython** unless otherwise specified.
|
||||
|
||||
### Example 1: Chat with Mixed Content
|
||||
|
||||
Send text, small image, and large file in one message.
|
||||
|
||||
#### Python/Micropython
|
||||
```python
|
||||
from nats_bridge import smartsend
|
||||
|
||||
data = [
|
||||
("message_text", "Hello!", "text"),
|
||||
("user_avatar", image_data, "image"),
|
||||
("large_document", large_file_data, "binary")
|
||||
]
|
||||
|
||||
env, env_json_str = smartsend("/chat/room1", data, fileserver_url="http://localhost:8080")
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
```javascript
|
||||
const { smartsend } = require('./src/NATSBridge');
|
||||
|
||||
const { env, env_json_str } = await smartsend("/chat/room1", [
|
||||
{ dataname: "message_text", data: "Hello!", type: "text" },
|
||||
{ dataname: "user_avatar", data: image_data, type: "image" },
|
||||
{ dataname: "large_document", data: large_file_data, type: "binary" }
|
||||
], {
|
||||
fileserver_url: "http://localhost:8080"
|
||||
});
|
||||
```
|
||||
|
||||
#### Julia
|
||||
```julia
|
||||
using NATSBridge
|
||||
@@ -580,35 +323,6 @@ env, env_json_str = NATSBridge.smartsend("/chat/room1", data; fileserver_url="ht
|
||||
|
||||
Send configuration data between platforms.
|
||||
|
||||
#### Python/Micropython
|
||||
```python
|
||||
from nats_bridge import smartsend
|
||||
|
||||
config = {
|
||||
"wifi_ssid": "MyNetwork",
|
||||
"wifi_password": "password123",
|
||||
"update_interval": 60
|
||||
}
|
||||
|
||||
data = [("config", config, "dictionary")]
|
||||
env, env_json_str = smartsend("/device/config", data)
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
```javascript
|
||||
const { smartsend } = require('./src/NATSBridge');
|
||||
|
||||
const config = {
|
||||
wifi_ssid: "MyNetwork",
|
||||
wifi_password: "password123",
|
||||
update_interval: 60
|
||||
};
|
||||
|
||||
const { env, env_json_str } = await smartsend("/device/config", [
|
||||
{ dataname: "config", data: config, type: "dictionary" }
|
||||
]);
|
||||
```
|
||||
|
||||
#### Julia
|
||||
```julia
|
||||
using NATSBridge
|
||||
@@ -627,36 +341,6 @@ env, env_json_str = NATSBridge.smartsend("/device/config", data)
|
||||
|
||||
Send tabular data using Apache Arrow IPC format.
|
||||
|
||||
#### Python/Micropython
|
||||
```python
|
||||
import pandas as pd
|
||||
from nats_bridge import smartsend
|
||||
|
||||
df = pd.DataFrame({
|
||||
"id": [1, 2, 3],
|
||||
"name": ["Alice", "Bob", "Charlie"],
|
||||
"score": [95, 88, 92]
|
||||
})
|
||||
|
||||
data = [("students", df, "table")]
|
||||
env, env_json_str = smartsend("/data/analysis", data)
|
||||
```
|
||||
|
||||
#### JavaScript
|
||||
```javascript
|
||||
const { smartsend } = require('./src/NATSBridge');
|
||||
|
||||
const tableData = [
|
||||
{ id: 1, name: "Alice", score: 95 },
|
||||
{ id: 2, name: "Bob", score: 88 },
|
||||
{ id: 3, name: "Charlie", score: 92 }
|
||||
];
|
||||
|
||||
const { env, env_json_str } = await smartsend("/data/analysis", [
|
||||
{ dataname: "students", data: tableData, type: "table" }
|
||||
]);
|
||||
```
|
||||
|
||||
#### Julia
|
||||
```julia
|
||||
using NATSBridge
|
||||
@@ -676,106 +360,6 @@ env, env_json_str = NATSBridge.smartsend("/data/analysis", data)
|
||||
|
||||
Bi-directional communication with reply-to support. The `smartsend` function now returns both the envelope object and a JSON string that can be published directly.
|
||||
|
||||
#### Python/Micropython (Requester)
|
||||
```python
|
||||
from nats_bridge import smartsend
|
||||
|
||||
env, env_json_str = smartsend(
|
||||
"/device/command",
|
||||
[("command", {"action": "read_sensor"}, "dictionary")],
|
||||
broker_url="nats://localhost:4222",
|
||||
reply_to="/device/response"
|
||||
)
|
||||
# env: MessageEnvelope object
|
||||
# env_json_str: JSON string for publishing to NATS
|
||||
|
||||
# The env_json_str can also be published directly using NATS request-reply pattern
|
||||
# nc.request("/device/command", env_json_str, reply_to="/device/response")
|
||||
```
|
||||
|
||||
#### Python/Micropython (Responder)
|
||||
```python
|
||||
import nats
|
||||
import asyncio
|
||||
from nats_bridge import smartreceive, smartsend
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/device/command"
|
||||
NATS_URL = "nats://localhost:4222"
|
||||
|
||||
async def main():
|
||||
nc = await nats.connect(NATS_URL)
|
||||
|
||||
async def message_handler(msg):
|
||||
# Receive and parse the incoming message envelope
|
||||
env = smartreceive(msg.data)
|
||||
|
||||
# Extract reply_to from the envelope metadata
|
||||
reply_to = env["reply_to"]
|
||||
|
||||
for dataname, data, type in env["payloads"]:
|
||||
if data.get("action") == "read_sensor":
|
||||
response = {"sensor_id": "sensor-001", "value": 42.5}
|
||||
# Send response to the reply_to subject from the request
|
||||
if reply_to:
|
||||
smartsend(reply_to, [("data", response, "dictionary")])
|
||||
|
||||
sid = await nc.subscribe(SUBJECT, cb=message_handler)
|
||||
await asyncio.sleep(120)
|
||||
await nc.close()
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
#### JavaScript (Requester)
|
||||
```javascript
|
||||
const { smartsend } = require('./src/NATSBridge');
|
||||
|
||||
const { env, env_json_str } = await smartsend("/device/command", [
|
||||
{ dataname: "command", data: { action: "read_sensor" }, type: "dictionary" }
|
||||
], {
|
||||
broker_url: "nats://localhost:4222",
|
||||
reply_to: "/device/response"
|
||||
});
|
||||
```
|
||||
|
||||
#### JavaScript (Responder)
|
||||
```javascript
|
||||
const { smartreceive, smartsend } = require('./src/NATSBridge');
|
||||
const { connect } = require('nats');
|
||||
|
||||
// Configuration
|
||||
const SUBJECT = "/device/command";
|
||||
const NATS_URL = "nats://localhost:4222";
|
||||
|
||||
async function main() {
|
||||
const nc = await connect({ servers: [NATS_URL] });
|
||||
|
||||
const sub = nc.subscribe(SUBJECT);
|
||||
|
||||
for await (const msg of sub) {
|
||||
const env = await smartreceive(msg);
|
||||
|
||||
// Extract reply_to from the envelope metadata
|
||||
const replyTo = env["reply_to"];
|
||||
|
||||
for (const payload of env.payloads) {
|
||||
if (payload.dataname === "command" && payload.data.action === "read_sensor") {
|
||||
const response = { sensor_id: "sensor-001", value: 42.5 };
|
||||
// Send response to the reply_to subject from the request
|
||||
if (replyTo) {
|
||||
await smartsend(replyTo, [
|
||||
{ dataname: "data", data: response, type: "dictionary" }
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
#### Julia (Requester)
|
||||
```julia
|
||||
using NATSBridge
|
||||
@@ -822,70 +406,9 @@ end
|
||||
test_responder()
|
||||
```
|
||||
|
||||
### Example 5: Micropython IoT Device
|
||||
### Example 5: IoT Device Sensor Data
|
||||
|
||||
Lightweight Micropython device sending sensor data.
|
||||
|
||||
#### Micropython
|
||||
```python
|
||||
import nats
|
||||
import asyncio
|
||||
from nats_bridge import smartsend, smartreceive
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/device/sensors"
|
||||
NATS_URL = "nats://localhost:4222"
|
||||
|
||||
async def main():
|
||||
nc = await nats.connect(NATS_URL)
|
||||
|
||||
# Send sensor data
|
||||
data = [("temperature", "25.5", "text"), ("humidity", 65, "dictionary")]
|
||||
smartsend("/device/sensors", data, broker_url="nats://localhost:4222")
|
||||
|
||||
# Receive commands - msg comes from the callback
|
||||
async def message_handler(msg):
|
||||
env = smartreceive(msg.data)
|
||||
for dataname, data, type in env["payloads"]:
|
||||
if type == "dictionary" and data.get("action") == "reboot":
|
||||
# Execute reboot
|
||||
pass
|
||||
|
||||
sid = await nc.subscribe(SUBJECT, cb=message_handler)
|
||||
await asyncio.sleep(120)
|
||||
await nc.close()
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
#### JavaScript (Receiver)
|
||||
```javascript
|
||||
const { smartreceive } = require('./src/NATSBridge');
|
||||
const { connect } = require('nats');
|
||||
|
||||
// Configuration
|
||||
const SUBJECT = "/device/sensors";
|
||||
const NATS_URL = "nats://localhost:4222";
|
||||
|
||||
async function main() {
|
||||
const nc = await connect({ servers: [NATS_URL] });
|
||||
|
||||
const sub = nc.subscribe(SUBJECT);
|
||||
|
||||
for await (const msg of sub) {
|
||||
const env = await smartreceive(msg);
|
||||
for (const payload of env.payloads) {
|
||||
if (payload.dataname === "temperature") {
|
||||
console.log(`Temperature: ${payload.data}`);
|
||||
} else if (payload.dataname === "humidity") {
|
||||
console.log(`Humidity: ${payload.data}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
IoT device sending sensor data.
|
||||
|
||||
#### Julia (Receiver)
|
||||
```julia
|
||||
@@ -921,53 +444,6 @@ test_receiver()
|
||||
|
||||
Run the test scripts to verify functionality:
|
||||
|
||||
### Python/Micropython
|
||||
|
||||
```bash
|
||||
# Basic functionality test
|
||||
python test/test_micropython_basic.py
|
||||
|
||||
# Text message exchange
|
||||
python test/test_micropython_text_sender.py
|
||||
python test/test_micropython_text_receiver.py
|
||||
|
||||
# Dictionary exchange
|
||||
python test/test_micropython_dict_sender.py
|
||||
python test/test_micropython_dict_receiver.py
|
||||
|
||||
# File transfer
|
||||
python test/test_micropython_file_sender.py
|
||||
python test/test_micropython_file_receiver.py
|
||||
|
||||
# Mixed payload types
|
||||
python test/test_micropython_mixed_sender.py
|
||||
python test/test_micropython_mixed_receiver.py
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
||||
```bash
|
||||
# Text message exchange
|
||||
node test/test_js_text_sender.js
|
||||
node test/test_js_text_receiver.js
|
||||
|
||||
# Dictionary exchange
|
||||
node test/test_js_dict_sender.js
|
||||
node test/test_js_dict_receiver.js
|
||||
|
||||
# File transfer
|
||||
node test/test_js_file_sender.js
|
||||
node test/test_js_file_receiver.js
|
||||
|
||||
# Mixed payload types
|
||||
node test/test_js_mix_payload_sender.js
|
||||
node test/test_js_mix_payloads_receiver.js
|
||||
|
||||
# Table exchange
|
||||
node test/test_js_table_sender.js
|
||||
node test/test_js_table_receiver.js
|
||||
```
|
||||
|
||||
### Julia
|
||||
|
||||
```julia
|
||||
|
||||
Reference in New Issue
Block a user