Asv.Common 3.7.4 Help

Asv.IO

Asv.IO separates byte transport, protocol decoding, message processing, and logical devices. An application can use the same connection contracts with different protocols without depending on concrete packet classes or transport implementations.

This section follows the architectural guides for Asv.Modeling: contracts first, then data flow, ownership, and short examples. The current source and tests are authoritative for exact behavior.

Layers

Transport bytes

Endpoint and parsers

Port

Router

DeviceExplorer

Client devices and microservices

IProtocolMessage

Optional IVisitable fields

The receive path above describes aggregation. Sending goes from a chosen connection toward its endpoints. A parser recognizes protocol messages; a device factory identifies logical devices from those messages. These are separate responsibilities.

Area

Main contracts

Guide

Construction and decoding

IProtocolFactory, IProtocolBuilder, IProtocolParser

Protocols

Transport and aggregation

IProtocolConnection, IProtocolRouter, IProtocolPort, IProtocolEndpoint

Connections

Processing and formatting

IProtocolFeature, IProtocolMessageFormatter

Features and formatters

Binary representation and outbound encoding

ISpanSerializable, ISizedSpanSerializable, IProtocolMessage, IProtocolEncoder

Serialization

Structured field access

IVisitable, IVisitor, Field, IFieldType

Fields and visitors

Device identity and lifecycle

IDeviceExplorer, IClientDeviceFactory, DeviceAddress, IClientDevice

Devices

A Hardware-Free Exchange

The example protocol is included in the package and can be used with a virtual connection. This exchange does not open network or serial ports.

using Asv.IO; using R3; var factory = Protocol.Create(builder => { builder.Protocols.RegisterExampleProtocol(); }); await using var link = factory.CreateVirtualConnection(printMessagesToLog: false); using var subscription = link.Client.OnRxMessage.Subscribe(message => { Console.WriteLine($"{message.Protocol.Name}: {message.Name}"); }); await link.Server.Send(new ExampleMessage2 { SenderId = 1, Value1 = 42, Value3 = "Virtual exchange", Value5 = 12.5f, });

A virtual connection has client and server sides. It serializes and parses messages between those sides, so it is useful for checking more than a direct object callback. Transport-specific behavior, reconnects, and queueing still require separate validation.

Boundaries To Keep Explicit

  • An endpoint identifies a transport connection. It does not necessarily identify one logical device.

  • A message name or message ID identifies a message kind, not its sender.

  • IProtocolMessage guarantees serialization and basic identity; it does not require IVisitable or a device identifier.

  • A connection's TX event is local to that connection level. Router TX and endpoint TX do not describe the same stage.

  • IDeviceExplorer discovers and manages devices through registered factories. Its TryIdentify method attributes a message source to a currently discovered device using optional factory addresses; lookup returns false before discovery and does not create devices or refresh liveness.

  • IDeviceExplorer.TryGetSourceAddress and TryGetDeviceAddress extract canonical addresses without requiring discovery. They use factory order, remain available after disposal, and do not change device state or liveness.

Source Map

The main implementation areas are src/Asv.IO/Protocol, src/Asv.IO/Serializable, src/Asv.IO/Visitable, and src/Asv.IO/Devices. Executable examples live in src/Asv.IO/Example; matching tests are under src/Asv.IO.Test.

26 October 2026