Raw TCP Nodes
Some equipment speaks no protocol you can name — a scale that emits a weight line, a label printer that takes ZPL, a legacy controller with a bespoke ASCII command set. The raw TCP nodes give a pipeline a byte-level socket to those devices: you send the bytes the device expects and read the bytes it answers with.
There are three nodes, one per direction of traffic. Setting up the connection they run over (host, port, connection mode, TLS, the egress guard) is covered in the TCP connector guide.
Configuration Quick Reference
| Field | What you choose | Details |
|---|---|---|
| Parameters | Connection, Function, Function Parameters, Timeout Override | Select the TCP connection profile, the function, its parameters (with expression support), and optionally a per-call timeout. |
| Settings | Description, Timeout (seconds), Retry on Timeout, Retry on Fail, On Error | Node description, maximum execution time, retry behavior, and error handling. All execution settings default to pipeline-level values. |
The three nodes
| Node | Purpose | Common Use Cases |
|---|---|---|
| TCP Send | Write bytes to the device and return | Fire a print job, push a setpoint frame, acknowledge a device |
| TCP Receive | Read up to N bytes that are already waiting | Drain a scale's weight line, read an unsolicited status frame |
| TCP Request | Write bytes, then read the reply on the same socket | Any request/response command set — the usual choice |
A fourth function, TCP Stream, is a trigger, not a node: it fires a pipeline for every chunk a stream-mode connection receives, and only exists on a connection whose Connection Mode is stream.
The connection's Connection Mode decides what is possible. In perCall mode the connector opens a fresh socket for every write and closes it immediately — there is nothing to read from, and TCP Receive refuses with a message saying so. Use persistent (or stream) mode for Receive, and for a Request whose device answers on a socket it expects to stay open.
Encoding
Every one of these nodes carries bytes, and the function's Encoding decides how those bytes appear as text in your pipeline:
| Encoding | Sending | Receiving |
|---|---|---|
utf8 / ascii | Your string's bytes go on the wire | The bytes come back as text |
hex | Your string is parsed as hex pairs (0102FF) | The bytes come back as a hex string |
base64 | Your string is base64-decoded | The bytes come back base64-encoded |
bytes | Your string is base64-decoded | The bytes come back base64-encoded |
bytes and base64 behave identically on the wire. JSON has no binary type, so raw bytes travel through a pipeline as base64; bytes is the connection default because it is lossless for any payload. Pick hex or base64/bytes for binary protocols: text encodings mangle bytes that are not valid characters. The connector guide has the full table, including the ascii rejection rule.
Output
Each TCP node delivers its data under result, and execution facts (success, functionId, durationMs, timestamp) under _metadata:
| Node | Expression | Description |
|---|---|---|
| TCP Send | $node["Name"].result.bytesWritten | How many bytes went onto the socket |
| TCP Receive | $node["Name"].result.data | The bytes read, encoded as the function's encoding says |
$node["Name"].result.bytesRead | How many bytes were read before the read ended | |
$node["Name"].result.closed | true when the peer closed the connection during this read | |
| TCP Request | $node["Name"].result.data | The reply bytes — this is the answer you act on |
$node["Name"].result.bytesWritten | How many bytes the request wrote | |
$node["Name"].result.bytesRead | How many bytes the reply carried | |
$node["Name"].result.closed | true when the peer closed the connection during the read | |
| all three | $node["Name"]._metadata.method, $node["Name"]._metadata.connectionId, $node["Name"]._metadata.protocol, $node["Name"]._metadata.endpoint, $node["Name"]._metadata.mode | The call's own facts: the operation, the connection it ran over, tcp, the host:port it spoke to, and the connection mode (perCall, persistent or stream) |
On a persistent connection the socket is shared across the pipeline's calls. A Receive returns everything buffered since the last read — a device greeting, the echo of an earlier Send, and the frame you actually wanted, all in one string. Parse for your delimiter rather than assuming result.data holds exactly one message.
bytesWritten is not a delivery receiptIt counts what the connector handed to the kernel. TCP will retransmit and eventually surface a broken connection, but a successful write does not mean the device parsed, accepted, or acted on the frame — only a reply proves that. Use TCP Request when you need the answer.