Raw TCP client connections for implementing binary protocols (Postgres, Redis, SMTP, ...) directly in Hot.
Connections are opaque handles owned by the runtime and live for the
duration of the run or task that opened them. Use ::hot::tls/upgrade
to switch an open connection to TLS in place (STARTTLS style).
For HTTP use ::hot::http; for WebSockets use ::hot::ws.
Functions
close
fn (conn: TcpConnection): Bool
Close the connection. Safe to call more than once.
Example
::tcp/close(conn)
connect
fn (host: Str, port: Int): TcpConnection
fn (host: Str, port: Int, options: TcpOptions): TcpConnection
Open a TCP connection to host:port.
Returns a TcpConnection. Fails with an error Result when the
connection cannot be established within the timeout.
Examples
// Simple connection
conn ::tcp/connect("db.example.com", 5432)
// With a shorter connect timeout
conn ::tcp/connect("db.example.com", 5432, TcpOptions({timeout: 5000}))
is-open
fn (conn: TcpConnection): Bool
Check whether the connection is still open (close has not been
called and no fatal error has occurred).
Note this does not probe the peer: a connection the other side has
dropped reports open until a read returns null or a write fails.
Example
if(::tcp/is-open(conn), send-more(conn), reconnect())
read
fn (conn: TcpConnection, max: Int): Bytes?
fn (conn: TcpConnection, max: Int, options: ReadOptions): Bytes?
Read up to max bytes from the connection.
Blocks until at least one byte is available and returns whatever has
arrived (which may be fewer than max bytes). Returns null when the
peer has closed the connection. Fails with an error Result when the
timeout expires — for protocol framing prefer read-exact.
Example
data ::tcp/read(conn, 4096)
if(is-null(data), handle-disconnect(), process(data))
read-exact
fn (conn: TcpConnection, n: Int): Bytes
fn (conn: TcpConnection, n: Int, options: ReadOptions): Bytes
Read exactly n bytes from the connection.
Blocks until all n bytes have arrived. Fails with an error Result
when the peer closes the connection first or the timeout expires.
This is the building block for length-prefixed protocol framing:
Example
::bytes ::hot::bytes
// Read a Postgres-style message: 1-byte type + 4-byte length + body
msg-type ::tcp/read-exact(conn, 1)
len-bytes ::tcp/read-exact(conn, 4)
body-len sub(::bytes/to-int(len-bytes), 4)
body ::tcp/read-exact(conn, body-len)
write
fn (conn: TcpConnection, data: Bytes | Str): Int
Write data to the connection and flush it.
Bytes are written as-is; Str values are written as UTF-8.
Returns the number of bytes written.
Example
::bytes ::hot::bytes
n ::tcp/write(conn, concat(::bytes/from-int(length(payload), 4), payload))
Types
ReadOptions
ReadOptions type {
timeout: Int?
}
Options for read operations.
Fields
timeout— Read timeout in milliseconds (default:30000,0= block until data arrives)
TcpConnection
TcpConnection type {
id: Str,
host: Str,
port: Int,
tls: Bool
}
An open TCP connection returned by connect (and by ::hot::tls/upgrade).
Fields
id- Unique connection identifierhost- Host the connection was opened toport- Port the connection was opened totls- Whether the connection has been upgraded to TLS
Example
::tcp ::hot::tcp
::bytes ::hot::bytes
conn ::tcp/connect("example.com", 80)
::tcp/write(conn, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")
response ::tcp/read(conn, 65536)
::tcp/close(conn)
TcpOptions
TcpOptions type {
timeout: Int?,
nodelay: Bool?
}
Options for opening a TCP connection.
Fields
timeout— Connect timeout in milliseconds (default:30000,0= no timeout)nodelay— Disable Nagle's algorithm (default:true)