Delivery Image Node
Instead of saving the render, this node pushes it down a WebSocket
- image
The Delivery Image Node is Save Image's antisocial sibling. Same position in the graph - it's the last node your image passes through - but instead of writing a PNG into ComfyUI/output/, it packs the finished render and shoves it down a WebSocket to a server you point it at. If that sounds niche, it is. This isn't a node for the desktop workflow where you drag the result back onto the canvas; it's for people running ComfyUI headless as a render engine, where something upstream - a web app, a job queue - asked for an image and expects the finished file pushed back over the wire rather than having to go fetch it.
The inputs give the game away before the README does. request_job_id is a string an orchestrator hands the run, and secret_token is a shared secret the receiving server checks against. This node was built to be driven from an API, tagged with a job ID, and trusted to deliver the result home. It's from a pack by 0nyx Networks (published as "m10i"), and it's a thin, open-source two-node pack - this one and a video sibling.
How it works
The mechanism is small and honest. Your image tensor becomes a PIL image, then PNG or lossless WEBP bytes. Those bytes go into a msgpack envelope with a fixed shape: type: "notification-from-pixel-socket" plus jobId, blobData, imageLength, fileExtension, mimeType, secretToken, and a millisecond timestamp. The whole thing is zstd-compressed at level 22, then sent as one binary frame over a fresh WebSocket connection that opens, sends, and closes. No keep-alive, no reconnect - one shot per run.
The optional oxipng_level input (0–6, default 0) is the only knob beyond the basics: if you set it above 0, the PNG gets an oxipng recompression pass before it ships, which can meaningfully shrink big renders. It only applies to the PNG path; WEBP skips it.
The inputs that actually matter
image- wire your final output here.websocket_url- thewss://endpoint that should receive the blob. The default,wss://example.foundation0.link/ws/streaming, is a placeholder; theexample.prefix is not decorative.secret_token- a shared secret the receiver checks. The default is literally the stringgenerate_random_token, so don't ship a workflow without changing it.request_job_id- which job this render belongs to, supplied by whatever queued the run.file_format- PNG (default) or WEBP.
It has no outputs - it's a terminal output node, which also means the engine treats it as a node that always runs and caches backward from it.
How to install it
It's on the Comfy registry, so the easy path is ComfyUI Manager: search pixel-socket-extensions-for-comfyui and install. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/0nyx-networks/pixel-socket-extensions-for-comfyui
Then restart ComfyUI. The requirements.txt pulls in msgpack-python, websocket-client, zstd, pyoxipng (a Rust wheel, so first install is a little heavy), plus pillow, numpy, httpx and piexif. No model files, nothing to download beyond that. One real compatibility catch: the pack is written against ComfyUI's newer backend API - comfy_api.latest, ComfyNode, a comfy_entrypoint() instead of NODE_CLASS_MAPPINGS. Old ComfyUI builds won't load it, so if the nodes are missing after install, update ComfyUI first.
Common issues
Silent failure is the trap. Look at the source and you'll see every send is wrapped in try/except - a failed connection just prints WebSocket error: ... to the console and the node still reports success. A wrong URL, a dead server, a revoked token: all of them give you a green checkmark and nothing delivered. Always check the terminal after a run.
The defaults go nowhere. Queue this with default settings and it dutifully connects to a placeholder domain that isn't your server. Nothing in the node tells you it failed.
No local fallback. Because it replaces Save Image rather than sitting next to it, a failed send means the render exists nowhere. Keep a Save Image in parallel until you trust the pipe.
One honest caveat on the security side: a node whose whole job is to phone home with bytes is exactly the shape that deserves a quick read before you wire it into anything with real data. This one is small - the deliverable logic is a couple hundred lines - and it only sends to the URL you give it, but it does send your generated image over the network, so use wss:// and a token that isn't a placeholder.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| file_format | COMBO | PNG | 2 options: PNG, WEBP |
| websocket_url | STRING | wss://example.foundation0.link/ws/streaming | — |
| secret_token | STRING | generate_random_token | — |
| request_job_id | STRING | <REQUEST_JOB_ID> | — |
| oxipng_levelopt | INT | 00–6 | — |
Outputs (0)
No outputs