diff --git a/README.md b/README.md index fc472b6..73858af 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ env, env_json_str = smartpack( "/chat/room1", data, broker_url="nats://localhost:4222", - size_threshold=100000 # 100KB for MicroPython + size_threshold=100000 ) print("Message sent!") ``` @@ -192,18 +192,16 @@ using msghandler, NATS conn = NATS.connect("nats.yiem.cc") NATS.subscribe(conn, "test.topic") do msg - println("Received message on $(msg.subject)") - payloads = String(msg.payload) - - # Use NATSBridge.smartreceive to handle the data - # API: smartreceive(msg, download_handler; max_retries, base_delay, max_delay) - envelope = msghandler.smartunpack( - payloads; - max_retries = 5, - base_delay = 100, - max_delay = 5000 - ) - println(envelope.payloads[1]) + println("Received message on $(msg.subject)") + envelope_json_str = String(msg.payload) + + envelope = msghandler.smartunpack( + envelope_json_str; + max_retries = 5, + base_delay = 100, + max_delay = 5000 + ) + println(envelope.payloads[1]) end ``` @@ -359,16 +357,16 @@ env, env_json_str = await msghandler.smartpack( #### MicroPython ```python -from msghandler import msghandler +from msghandler import smartpack # Limited to direct transport (< 100KB threshold) -env, env_json_str = msghandler.smartpack( - subject, - data, # List of (dataname, data, type) tuples +env, env_json_str = smartpack( + "/device/config", + [("config", config, "dictionary")], broker_url="nats://localhost:4222", - size_threshold=100000 # Lower threshold for memory constraints + size_threshold=100000 ) -# Returns: Tuple[Dict, str] +print("Message sent!") ``` ### smartunpack @@ -442,16 +440,16 @@ env = await msghandler.smartunpack( #### MicroPython ```python -from msghandler import msghandler +from msghandler import smartunpack -env = msghandler.smartunpack( +env = smartunpack( msg, fileserver_download_handler=_sync_fileserver_download, max_retries=3, base_delay=100, max_delay=1000 ) -# Returns: Dict with "payloads" key +print("Received payloads:", env["payloads"]) ``` --- @@ -516,33 +514,63 @@ import msghandler from './src/msghandler_csr.js'; const data = [ ["message_text", "Hello!", "text"], - ["user_avatar", imageData, "image"], - ["large_document", largeFileData, "binary"] + ["user_avatar", image_data, "image"] ]; const [env, env_json_str] = await msghandler.smartpack( "/chat/room1", data, - { broker_url: 'ws://localhost:4222', fileserver_url: 'http://localhost:8080' } + { broker_url: 'ws://localhost:4222' } ); +console.log("Message sent!"); ``` #### Python ```python -from msghandler import msghandler +import asyncio +from msghandler import smartpack +async def main(): + image_data = open("user_avatar.png", "rb").read() + large_file_data = open("large_document.pdf", "rb").read() + + data = [ + ("message_text", "Hello!", "text"), + ("user_avatar", image_data, "image"), + ("large_document", large_file_data, "binary") + ] + + env, env_json_str = await smartpack( + "/chat/room1", + data, + fileserver_url="http://localhost:8080" + ) + print("Message sent!") + +if __name__ == "__main__": + asyncio.run(main()) +``` + +#### MicroPython + +```python +from msghandler import smartpack + +# Note: MicroPython only supports direct transport (< 100KB threshold) +# Large files must be uploaded via file server first data = [ ("message_text", "Hello!", "text"), - ("user_avatar", image_data, "image"), - ("large_document", large_file_data, "binary") + ("user_avatar", image_bytes, "image") ] -env, env_json_str = await msghandler.smartpack( +env, env_json_str = smartpack( "/chat/room1", data, - fileserver_url="http://localhost:8080" + broker_url="nats://localhost:4222", + size_threshold=100000 ) +print("Message sent!") ``` ### Example 2: Dictionary Exchange @@ -579,12 +607,34 @@ const [env, env_json_str] = await msghandler.smartpack( "/device/config", [["config", config, "dictionary"]] ); +console.log("Message sent!"); ``` #### Python ```python -from msghandler import msghandler +import asyncio +from msghandler import smartpack + +async def main(): + config = { + "wifi_ssid": "MyNetwork", + "wifi_password": "password123", + "update_interval": 60 + } + + data = [("config", config, "dictionary")] + env, env_json_str = await smartpack("/device/config", data) + print("Message sent!") + +if __name__ == "__main__": + asyncio.run(main()) +``` + +#### MicroPython + +```python +from msghandler import smartpack config = { "wifi_ssid": "MyNetwork", @@ -593,7 +643,13 @@ config = { } data = [("config", config, "dictionary")] -env, env_json_str = await msghandler.smartpack("/device/config", data) +env, env_json_str = smartpack( + "/device/config", + data, + broker_url="nats://localhost:4222", + size_threshold=100000 +) +print("Message sent!") ``` ### Example 3: Table Data (Arrow IPC) @@ -654,8 +710,6 @@ env, env_json_str = await msghandler.smartpack("/data/analysis", data) ```javascript import msghandler from './src/msghandler_csr.js'; -// Browser uses jsontable (JSON array of objects) instead of arrowtable -// Apache Arrow is not compatible with browsers const df = [ { id: 1, name: "Alice", score: 95 }, { id: 2, name: "Bob", score: 88 }, @@ -664,9 +718,33 @@ const df = [ const [env, env_json_str] = await msghandler.smartpack( "/data/analysis", - [["students", df, "jsontable"]], // Use jsontable for browser + [["students", df, "jsontable"]], { broker_url: 'ws://localhost:4222' } ); +console.log("Message sent!"); +``` + +#### MicroPython + +```python +from msghandler import smartpack + +# Note: MicroPython only supports direct transport (< 100KB threshold) +# MicroPython doesn't support Arrow IPC, only jsontable +df = [ + {"id": 1, "name": "Alice", "score": 95}, + {"id": 2, "name": "Bob", "score": 88}, + {"id": 3, "name": "Charlie", "score": 92} +] + +data = [("students", df, "jsontable")] +env, env_json_str = smartpack( + "/data/analysis", + data, + broker_url="nats://localhost:4222", + size_threshold=100000 +) +print("Message sent!") ``` ### Example 4: Request-Response Pattern @@ -676,32 +754,44 @@ Bi-directional communication with reply-to support. #### Julia ```julia -using msghandler +using msghandler, NATS # Requester -env, env_json_str = smartpack( +env, env_json_str = msghandler.smartpack( "/device/command", [("command", Dict("action" => "read_sensor"), "dictionary")]; broker_url="nats://localhost:4222", reply_to="/device/response" ) +conn = NATS.connect("nats://localhost:4222") +NATS.publish(conn, "/device/command", env_json_str) +NATS.drain(conn) + # Receiver (in separate application) -msg = NATS.subscription.next() -env = smartunpack(msg) -# Process request and send response -response_env, response_json = smartpack( - "/device/response", - [("result", Dict("value" => 42), "dictionary")], - reply_to="/device/command", - reply_to_msg_id=env["msg_id"] -) +conn = NATS.connect("nats://localhost:4222") +NATS.subscribe(conn, "/device/command") do msg + env = msghandler.smartunpack(msg) + println("Received command: ", env["payloads"]) + + result = Dict("value" => 42) + response_env, response_json = msghandler.smartpack( + "/device/response", + [("result", result, "dictionary")], + reply_to="/device/command", + reply_to_msg_id=env["msg_id"] + ) + + NATS.publish(conn, "/device/response", response_json) + NATS.drain(conn) +end ``` #### JavaScript (Node.js) ```javascript import msghandler from './src/msghandler_ssr.js'; +import { connect } from 'nats'; // Requester const [env, env_json_str] = await msghandler.smartpack( @@ -709,11 +799,76 @@ const [env, env_json_str] = await msghandler.smartpack( [["command", { action: "read_sensor" }, "dictionary"]], { broker_url: 'nats://localhost:4222', reply_to: '/device/response' } ); +const nc = await connect({ port: 4222 }); +nc.publish("/device/command", env_json_str); +await nc.flush(); + +// Receiver (in separate application) +const nc = await connect({ port: 4222 }); +const sub = nc.subscribe("/device/command"); +for await (const msg of sub) { + const env = await msghandler.smartunpack(msg); + console.log("Received command:", env.payloads); + + const response_env, response_json = await msghandler.smartpack( + "/device/response", + [["result", { value: 42 }, "dictionary"]], + { reply_to: '/device/command', reply_to_msg_id: env.msg_id } + ); + + nc.publish("/device/response", response_json); + await nc.flush(); +} +``` + +#### Python + +```python +import asyncio +from msghandler import smartpack + +async def main(): + # Requester + env, env_json_str = await smartpack( + "/device/command", + [("command", {"action": "read_sensor"}, "dictionary")], + broker_url="nats://localhost:4222", + reply_to="/device/response" + ) + print("Request sent!") + + # Receiver (in separate application) + # await nats_consumer.next() + # env = await smartunpack(msg) + # Process request and send response + # response_env, response_json = await smartpack( + # "/device/response", + # [("result", {"value": 42}, "dictionary")], + # reply_to="/device/command", + # reply_to_msg_id=env["msg_id"] + # ) + +if __name__ == "__main__": + asyncio.run(main()) +``` + +#### JavaScript (Browser) + +```javascript +import msghandler from './src/msghandler_csr.js'; + +// Requester +const [env, env_json_str] = await msghandler.smartpack( + "/device/command", + [["command", { action: "read_sensor" }, "dictionary"]], + { broker_url: 'ws://localhost:4222', reply_to: '/device/response' } +); +console.log("Request sent!"); // Receiver (in separate application) // const msg = await natsConsumer.next(); // const env = await msghandler.smartunpack(msg); -// Process request and send response +// console.log("Received command:", env.payloads); // const response_env, response_json = await msghandler.smartpack( // "/device/response", // [["result", { value: 42 }, "dictionary"]], @@ -721,29 +876,20 @@ const [env, env_json_str] = await msghandler.smartpack( // ); ``` -#### Python +#### MicroPython ```python -from msghandler import msghandler +from msghandler import smartpack # Requester -env, env_json_str = await msghandler.smartpack( +env, env_json_str = smartpack( "/device/command", [("command", {"action": "read_sensor"}, "dictionary")], broker_url="nats://localhost:4222", - reply_to="/device/response" + reply_to="/device/response", + size_threshold=100000 ) - -# Receiver (in separate application) -# msg = await nats_consumer.next() -# env = await msghandler.smartunpack(msg) -# Process request and send response -# response_env, response_json = await msghandler.smartpack( -# "/device/response", -# [("result", {"value": 42}, "dictionary")], -# reply_to="/device/command", -# reply_to_msg_id=env["msg_id"] -# ) +print("Request sent!") ``` ---