# `NebulaGraphEx.Transport`
[🔗](https://github.com/VChain/nebula_graph_ex/blob/v0.1.10/lib/nebula_graph_ex/transport.ex#L1)

Low-level TCP/SSL socket abstraction with Thrift framed transport.

NebulaGraph uses 4-byte big-endian length-prefixed framing over plain TCP
(or TLS). This module owns the socket lifecycle and provides `send_frame/2`
and `recv_frame/2` which handle the framing transparently.

Callers (i.e. `NebulaGraphEx.Connection`) should not use raw socket calls —
always go through this module so framing and SSL are handled uniformly.

# `opts`

```elixir
@type opts() :: keyword()
```

# `socket`

```elixir
@type socket() :: :gen_tcp.socket() | :ssl.sslsocket()
```

# `close`

```elixir
@spec close(socket()) :: :ok
```

Closes the socket. Works for both plain TCP and SSL sockets.

# `connect`

```elixir
@spec connect(String.t(), :inet.port_number(), opts()) ::
  {:ok, socket()} | {:error, term()}
```

Opens a TCP (or TLS) connection to `host:port`.

## Options

* `:ssl` — `boolean`, enable TLS. Default: `false`.
* `:ssl_opts` — keyword list passed to `:ssl.connect/4`. Default: `[]`.
* `:connect_timeout` — timeout in ms. Default: `5_000`.
* `:send_timeout` — socket-level send timeout. Default: `15_000`.

Returns `{:ok, socket}` or `{:error, reason}`.

# `recv_frame`

```elixir
@spec recv_frame(socket(), timeout()) :: {:ok, binary()} | {:error, term()}
```

Receives one complete Thrift frame from the socket.

Reads the 4-byte length header first, then reads exactly that many bytes.
Returns `{:ok, payload}` or `{:error, reason}`.

# `send_frame`

```elixir
@spec send_frame(socket(), binary()) :: :ok | {:error, term()}
```

Sends a binary payload as a single Thrift frame.

Prepends the 4-byte big-endian length header automatically.

# `ssl?`

```elixir
@spec ssl?(socket()) :: boolean()
```

Returns `true` if the socket is an SSL socket.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
