Vixen
02b45cc4
csharp
public sealed class CompositeTransport

Several transports, listening at once, behind one.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

What it is for is one server accepting more than one kind of client. A desktop build should be on UDP and a browser build cannot be; a game that wants both has otherwise to run two servers with two worlds, or pick one and make somebody suffer for it. Here the session, replication and RPC layers see a single transport and never learn that half their players arrived over TCP.

Connection ids are rewritten, and that is the whole of the difficulty. Each inner transport numbers its own connections from one, so two of them will hand out the same number for different players within the first second. This one hands out ids of its own and keeps a map both ways, so the number a game sees is unique across every transport it is listening on — which is what everything above assumes and what nothing above checks.

The client half is a single choice, not a race. Composing servers is the useful direction: a client knows what it is and which address it was given. Starting every inner client at once and keeping whichever answered first is a different feature — transport fallback — and it belongs with the relay work rather than being smuggled in here, so a composite used as a client drives exactly the one it was told to.

Fields and properties (5)

  • public IReadOnlyList<ITransport> Transports

    The transports underneath, in the order they were given.

  • public ITransport ClientTransport

    Which of them a client half runs on.

  • public TransportCapabilities Capabilities
  • public TransportState ServerState

    Whether the server half is listening.

  • public TransportState ClientState

    Whether the client half is connected.

Methods (10)

  • public CompositeTransport(IReadOnlyList<ITransport> transports, int clientTransport = 0)

    Combines transports.

  • public void StartServer()

    Starts listening. Where — a port, an address, a relay — was fixed when the transport was constructed, which is what keeps this interface free of anything socket-shaped.

  • public void StopServer()

    Stops listening and disconnects everyone, reporting ServerStopped to both sides. Does nothing if the server half is already stopped.

  • public void StartClient()

    Begins connecting. Completion is reported to OnConnected on a later Poll, or refusal to OnDisconnected — never inline, so the caller has one code path for "connected in a microsecond over loopback" and "connected in 90 ms over the Atlantic".

  • public void StopClient()

    Disconnects the client half, reporting Requested to this side and RemoteRequested to the server. Does nothing if the client half is already stopped.

  • public void Disconnect(ConnectionId connection)

    Closes one connection from the server side, reporting Requested here and Kicked there. Does nothing if the connection is not one of ours.

  • public void SendToClient(ConnectionId connection, ReadOnlySpan<byte> payload, Channel channel)

    Sends to one connected client. Does nothing if the connection is not ours.

  • public void SendToServer(ReadOnlySpan<byte> payload, Channel channel)

    Sends to the server. Does nothing if the client half is not connected.

  • public void Poll(TimeSpan elapsed, ITransportEvents events)

    Advances the transport by and reports everything that has happened since the last call, in the order it happened, to .

  • public void Dispose()

    Disposes every transport underneath.

Used by (3)

  • CompositeOverLocalConformanceTestsVixen.Net.Transport.Composite.Tests
  • CompositeTransportTestsVixen.Net.Transport.Composite.Tests
  • RouterVixen.Net.Transport.Composite