---
id: pipes--port-listener
title: "Pipe listener"
summary: "Entry point of a flow that is called from other flows. It opens a local TCP pipe, registers it under its `Name`, emits every incoming request on `Request` and, for two-way listeners, sends whatever reaches `Response` back to the calling **Pipe client**. The component keeps the flow running."
audience: user
keywords: "request, response, start, name, istwoway"
---
# Pipe listener

Entry point of a flow that is called from other flows. It opens a local TCP pipe, registers it under its `Name`, emits every incoming request on `Request` and, for two-way listeners, sends whatever reaches `Response` back to the calling **Pipe client**. The component keeps the flow running.

## Pins

| Pin | Kind | Types | Description |
|---|---|---|---|
| Request | output | any (type of the connection) | Incoming request data with new metadata that carries the request id. |
| Response | input | any (type of the connection) | Response for the caller. Only for two-way listeners. |
| Start | start | any | Opens the pipe. When unconnected, the system calls it when the flow starts. |

The metadata of `Request` contains `Viaducta.Plugins.PortListener.PortListenerMetaData` (suggested name `PortRequest`) with `PortRequestId`, the id used to route the response.

## Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `Name` | string | `Port` | Required. Port name, unique among Pipe listeners of the flow, at most 128 characters. Pipe clients find the listener by flow id + this name. |
| `IsTwoWay` | boolean | `false` | `false`: one-way, the caller gets only an acknowledgement. `true`: request/response, the caller waits for the data that reaches `Response`. |

## Behaviour

- On start the listener takes a free TCP port on `127.0.0.1`, starts the pipe and registers it with the environment as `<flow id>/<Name>`. It is unregistered when the flow stops.
- The request type is the type on the `Request` connection (`NoInputData` when `Request` is unconnected); the response type is the type on the `Response` connection. A Pipe client imports exactly these types when it selects this listener.
- Incoming requests whose type does not match the request type are rejected; the caller receives an exception.
- Each request is emitted on `Request` with new metadata; correlation id and session id are taken over from the caller.
- One-way listener, or a caller in asynchronous mode: the acknowledgement is sent before the request is processed.
- Two-way listener: when a record reaches `Response`, its metadata's `PortRequestId` identifies the waiting request and the record is sent back as the response. Keep the metadata of the request through the flow up to `Response`; if the id is unknown (already answered or timed out) a warning is shown.
- An exception while processing a two-way request is sent back to the caller as an exception.
- Start-up checks (the flow fails to start): empty or too long `Name`, two listeners with the same `Name` in the flow, `IsTwoWay` = `true` without a `Response` connection, `IsTwoWay` = `false` with a `Response` connection.

## Notes

- `IsTwoWay` cannot be changed while the flow runs.
- Answer each two-way request exactly once. A request that never reaches `Response` keeps the caller waiting until its timeout; only the first response for a request is delivered.
- Renaming the listener breaks existing Pipe clients until they select it again.
- The pipe listens on the loopback address, so callers must run on the same machine.
- For one-way listeners an exception in the flow is only logged; the caller is not informed.

## Example

```json
{ "Name": "GetCustomer", "IsTwoWay": true }
```

**Pipe listener** `Request` → Table reader → Data mapper → **Pipe listener** `Response`
