Skip to content

Latest commit

 

History

History
106 lines (80 loc) · 3.21 KB

File metadata and controls

106 lines (80 loc) · 3.21 KB

Transports

ARCP is transport-agnostic. This SDK ships three implementations of ITransport, covering every scenario from network deployments to in-process testing.

Transport Spec Use case
WebSocketTransport §4.1 Network deployments. UTF-8 text frames; one JSON envelope per frame.
StdioTransport §4.2 Child-process agents. Newline-delimited JSON over an arbitrary Stream pair.
MemoryTransport n/a Tests and same-process runtime hosting.

WebSocket

var ws = new ClientWebSocket();
await ws.ConnectAsync(new Uri("ws://host:port/arcp"), CancellationToken.None);
ITransport transport = new WebSocketTransport(ws, ownsSocket: true);

Pass ownsSocket: true when you want transport.DisposeAsync() to close the underlying socket. Pass false if another owner controls it.

The server side is provided by Arcp.AspNetCore:

app.UseWebSockets(new WebSocketOptions
{
    KeepAliveInterval = Timeout.InfiniteTimeSpan, // let ARCP heartbeat handle liveness
});
app.MapArcp(server, o => o.Path = "/arcp");

See Arcp.AspNetCore for full options.

stdio

Use StdioTransport when the runtime runs as a child process of the client, or when the client is itself a child process.

Agent (child process):

// In Program.cs of the agent:
var server = new ArcpServer(options);
server.RegisterAgent("my-agent", handler);
var transport = StdioTransport.FromConsole();
await server.AcceptAsync(transport);

StdioTransport.FromConsole() reads from Console.OpenStandardInput() and writes to Console.OpenStandardOutput(). Agent code MUST write logs to stderr — any non-envelope byte on stdout will corrupt the channel.

Parent process spawning a child agent:

using var proc = Process.Start(new ProcessStartInfo
{
    FileName = "dotnet",
    Arguments = "run --project ./MyAgent",
    RedirectStandardInput  = true,
    RedirectStandardOutput = true,
    UseShellExecute        = false,
});
var transport = new StdioTransport(
    proc!.StandardOutput.BaseStream,
    proc.StandardInput.BaseStream);
await using var client = await ArcpClient.ConnectAsync(transport, options);

MemoryTransport

MemoryTransport.Pair() returns two linked transports — one for the client and one for the server — backed by in-process channels. No sockets, no serialization round-trip delay.

var (clientTransport, serverTransport) = MemoryTransport.Pair();
_ = server.AcceptAsync(serverTransport);
await using var client = await ArcpClient.ConnectAsync(clientTransport, options);

Preferred transport for:

  • Unit and integration tests.
  • Samples and quickstarts.
  • Same-process runtimes where network overhead is undesirable.

Adding tracing to any transport

Wrap any ITransport with WithTracing() from Arcp.Otel:

using Arcp.Otel;

var traced = transport.WithTracing();

The wrapper emits one OTel span per envelope (send and receive) and injects/extracts the W3C traceparent via envelope.extensions["x-vendor.opentelemetry.tracecontext"].

See Observability and the Arcp.Otel project page.