阶段 5
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-03-27
|
||||
@@ -0,0 +1,59 @@
|
||||
## Context
|
||||
|
||||
The current networking stack already shares transport, message routing, and session lifecycle vocabulary between client and server hosts. However, the shared runtime still owns exactly one `SessionManager`, which matches the client model but does not match a server that needs to track many remote peers concurrently while preserving the same login, timeout, heartbeat, and reconnect semantics.
|
||||
|
||||
The main constraint is backward compatibility for the client host. The Unity client should keep its simple single-session composition, while the server host gains an explicit multi-session orchestration layer instead of embedding per-peer lifecycle logic into handlers or transport internals.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Preserve `SessionManager` as the per-session finite state machine and lifecycle vocabulary owner.
|
||||
- Introduce a shared multi-session orchestration layer that can create, look up, evaluate, and remove many session managers keyed by remote identity.
|
||||
- Keep client composition simple by allowing the existing single-session runtime path to remain valid.
|
||||
- Make server-facing APIs explicit about per-session lookup, enumeration, lifecycle events, and cleanup triggers.
|
||||
|
||||
**Non-Goals:**
|
||||
- Redesign KCP transport session isolation or introduce a new wire protocol.
|
||||
- Change the meaning of existing connection states or heartbeat semantics.
|
||||
- Solve stage 6 QoS or synchronization policy work in the same change.
|
||||
- Move gameplay admission, authority, or player-object ownership into the shared lifecycle layer.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Keep `SessionManager` as a per-session state machine
|
||||
`SessionManager` already models one connection lifecycle correctly. Replacing it with a collection-aware type would force client and server concerns into the same API surface. The change will keep `SessionManager` focused on a single session and add a higher-level multi-session coordinator for hosts that manage many peers.
|
||||
|
||||
Alternative considered: make `SessionManager` itself collection-aware.
|
||||
Rejected because it would either expose server-only concepts to the client or create a type with dual responsibilities that is harder to test and reason about.
|
||||
|
||||
### Add a keyed multi-session coordinator above transport callbacks
|
||||
The new orchestration layer should own a mapping from remote identity to per-session `SessionManager` instances. Transport delivery, login results, inbound activity, heartbeat updates, timeout evaluation, and reconnect bookkeeping should be routed through this keyed coordinator rather than being inferred in message handlers.
|
||||
|
||||
Alternative considered: keep session dictionaries inside `ServerNetworkHost` only.
|
||||
Rejected because it would fork lifecycle orchestration away from the shared core and make server behavior harder to test without the host adapter.
|
||||
|
||||
### Preserve separate host adapters for client and server
|
||||
The Unity client should continue composing a single-session runtime with its main-thread dispatcher. The server host should compose the shared transport and message layer with the new multi-session orchestration path, exposing per-session inspection and events without inheriting Unity-specific assumptions.
|
||||
|
||||
Alternative considered: replace `SharedNetworkRuntime` with one universal runtime abstraction.
|
||||
Rejected because the client and server have materially different composition shapes; forcing one runtime abstraction would hide important ownership boundaries.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [More lifecycle objects] → Mitigation: keep `SessionManager` unchanged and centralize multi-session behavior in one coordinator with focused tests.
|
||||
- [Remote identity choice may leak transport details] → Mitigation: define a narrow session-key abstraction or standardize on the existing remote endpoint identity used by transport callbacks.
|
||||
- [Server cleanup bugs can leave stale sessions behind] → Mitigation: require explicit disconnect/removal scenarios and evaluation tests for session expiry.
|
||||
- [Client API drift during refactor] → Mitigation: keep the single-session runtime path as a first-class supported composition and verify it with regression tests.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Introduce the multi-session coordinator and per-session observation API in the shared network layer.
|
||||
2. Rewire `ServerNetworkHost` to use the coordinator for per-peer lifecycle bookkeeping.
|
||||
3. Leave the client host on the existing single-session runtime path, adding only compatibility glue if necessary.
|
||||
4. Add tests that cover client single-session regressions and server multi-session behavior side by side.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Whether the server session key should be the transport remote endpoint directly or a narrower shared abstraction.
|
||||
- Whether reconnect scheduling is meaningful for the server side, or should remain configurable per host/session policy.
|
||||
- How much session enumeration should be exposed publicly versus kept internal with event-based observation.
|
||||
@@ -0,0 +1,25 @@
|
||||
## Why
|
||||
|
||||
The current shared networking foundation exposes a single `SessionManager` lifecycle per runtime, which is sufficient for a client connected to one server but not for a server handling multiple remote peers concurrently. Extending the lifecycle model now prevents the server host from forking transport, login, timeout, and reconnect logic away from the shared network core.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Introduce shared multi-session lifecycle orchestration for hosts that manage more than one remote peer at a time.
|
||||
- Preserve the current single-session client flow while adding a server-oriented session collection API keyed by remote identity.
|
||||
- Define how transport events, login results, heartbeat liveness, timeout detection, and reconnect policy are applied per managed session instead of only per runtime.
|
||||
- Clarify which responsibilities stay in the shared session orchestration layer versus host-specific admission, cleanup, and gameplay reactions.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `multi-session-lifecycle`: Shared orchestration and observation of multiple concurrent network sessions, especially for server hosts that manage many remote peers.
|
||||
|
||||
### Modified Capabilities
|
||||
- `network-session-lifecycle`: The shared lifecycle vocabulary and heartbeat/reconnect rules must apply to each managed session, not only to a singleton runtime session.
|
||||
- `shared-network-foundation`: The shared runtime foundation must support both client-style single-session composition and server-style multi-session composition without introducing a protocol or transport fork.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected code: `SharedNetworkRuntime`, `SessionManager`, `ServerNetworkHost`, transport-to-session wiring, and lifecycle-related tests.
|
||||
- New APIs will likely introduce server-facing session lookup, enumeration, and per-session event observation.
|
||||
- Client-side runtime composition should remain compatible, but session orchestration responsibilities will be split more explicitly between single-session and multi-session hosts.
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Multi-session hosts manage per-peer lifecycle state
|
||||
The shared networking core SHALL provide a multi-session lifecycle coordinator for hosts that manage multiple concurrent remote peers. The coordinator MUST maintain distinct per-session lifecycle state keyed by remote identity rather than collapsing all peers into one runtime-level state.
|
||||
|
||||
#### Scenario: Server tracks two peers independently
|
||||
- **WHEN** a server host accepts transport activity from two different remote peers
|
||||
- **THEN** the multi-session coordinator creates or resolves two distinct managed sessions
|
||||
- **THEN** lifecycle changes for one peer do not overwrite or hide the state of the other peer
|
||||
|
||||
### Requirement: Multi-session hosts can observe and evaluate each managed session
|
||||
The multi-session lifecycle coordinator SHALL expose per-session lookup or enumeration and MUST evaluate timeout, heartbeat, login, and reconnect rules for each managed session independently using the shared session lifecycle vocabulary.
|
||||
|
||||
#### Scenario: Timeout affects only one managed session
|
||||
- **WHEN** one managed session stops receiving liveness updates while another session continues receiving heartbeat or message activity
|
||||
- **THEN** the timed-out session transitions through timeout or reconnect states according to policy
|
||||
- **THEN** the active session remains in its current healthy state
|
||||
|
||||
#### Scenario: Host can inspect current managed sessions
|
||||
- **WHEN** server-side code needs to inspect the current connection state of connected peers
|
||||
- **THEN** it can look up or enumerate managed sessions through the multi-session coordinator
|
||||
- **THEN** each entry exposes the shared session lifecycle state for that specific peer
|
||||
|
||||
### Requirement: Session removal is explicit and does not corrupt remaining peers
|
||||
The multi-session lifecycle coordinator SHALL support explicit removal or disconnection handling for one managed session without resetting unrelated sessions that remain active.
|
||||
|
||||
#### Scenario: Disconnect removes one session only
|
||||
- **WHEN** one remote peer disconnects or is evicted by the host
|
||||
- **THEN** the coordinator updates or removes that peer's managed session
|
||||
- **THEN** other managed sessions remain queryable and keep their own lifecycle state
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Session lifecycle distinguishes transport and login state
|
||||
The shared networking core SHALL expose an explicit session lifecycle model that distinguishes transport connectivity from login/authentication success. Hosts MUST be able to observe at least disconnected, transport-connected, login-pending, logged-in, login-failed, timed-out, and reconnecting lifecycle states for each managed session without inferring them from unrelated message handlers.
|
||||
|
||||
#### Scenario: Transport connect does not imply login success
|
||||
- **WHEN** the transport establishes a usable remote session but no login success message has been accepted yet
|
||||
- **THEN** the shared lifecycle reports a transport-connected or login-pending state for that managed session
|
||||
- **THEN** it does not report the session as logged in
|
||||
|
||||
#### Scenario: Login success advances lifecycle independently
|
||||
- **WHEN** the client or server session manager receives a successful login/authentication result for an active transport session
|
||||
- **THEN** the shared lifecycle transitions that managed session into the logged-in state
|
||||
- **THEN** hosts can react to that state change without conflating it with transport establishment
|
||||
|
||||
### Requirement: Timeout and reconnect are session-manager responsibilities
|
||||
The shared networking core SHALL manage timeout detection, disconnect transitions, and reconnect scheduling through session-manager components rather than implementing those decisions inside business message handlers. Hosts that manage multiple concurrent peers MUST apply these rules independently per managed session rather than collapsing timeout or reconnect state to the entire runtime.
|
||||
|
||||
#### Scenario: Timeout produces an observable reconnect transition
|
||||
- **WHEN** a reconnect-capable host has a session that times out
|
||||
- **THEN** the session manager emits a timeout-related lifecycle transition for that managed session
|
||||
- **THEN** it can subsequently move the session into a reconnecting or reconnect-pending state according to configured policy
|
||||
|
||||
#### Scenario: Login failure is distinct from transport disconnect
|
||||
- **WHEN** authentication or login fails while the transport session is still active
|
||||
- **THEN** the shared lifecycle reports a login-failed state for that managed session
|
||||
- **THEN** hosts can handle that failure separately from a transport disconnect or heartbeat timeout
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Shared runtime owns host-agnostic session lifecycle orchestration
|
||||
The shared network foundation SHALL include host-agnostic session lifecycle orchestration alongside transport startup and message routing. Client and server hosts MUST be able to compose the shared foundation with session orchestration that consumes transport events, login results, and heartbeat signals without depending on Unity-specific runtime types, while supporting both single-session client composition and multi-session server composition.
|
||||
|
||||
#### Scenario: Client host composes runtime with single-session lifecycle manager
|
||||
- **WHEN** the Unity client constructs its shared networking runtime
|
||||
- **THEN** that runtime includes shared session lifecycle management for its single remote session in addition to transport and message routing
|
||||
- **THEN** Unity-specific code remains responsible only for reacting to lifecycle state changes and driving host behavior
|
||||
|
||||
#### Scenario: Server host composes shared foundation with multi-session orchestration
|
||||
- **WHEN** a non-Unity server host constructs the runtime networking stack for multiple remote peers
|
||||
- **THEN** it uses the shared transport and message-routing foundation together with shared multi-session lifecycle orchestration
|
||||
- **THEN** server-specific cleanup, admission, and gameplay reactions stay in the server host adapter rather than forking the shared lifecycle contract
|
||||
@@ -0,0 +1,23 @@
|
||||
## 1. Shared Multi-Session Lifecycle Core
|
||||
|
||||
- [x] 1.1 Introduce a shared multi-session lifecycle coordinator that owns per-session `SessionManager` instances keyed by remote identity.
|
||||
- [x] 1.2 Add APIs for per-session lookup, enumeration, lifecycle event observation, and explicit session removal without changing the existing session state vocabulary.
|
||||
- [x] 1.3 Route transport activity, login results, heartbeat updates, timeout evaluation, and reconnect bookkeeping through the coordinator on a per-session basis.
|
||||
|
||||
## 2. Host Composition
|
||||
|
||||
- [x] 2.1 Rework `ServerNetworkHost` to use the shared multi-session coordinator instead of exposing only one runtime-level `SessionManager`.
|
||||
- [x] 2.2 Preserve the current client-side single-session composition path so `NetworkManager` and `SharedNetworkRuntime` remain valid for one-server connectivity.
|
||||
- [x] 2.3 Define how remote identity is mapped into session keys and ensure session cleanup does not disturb unrelated peers.
|
||||
|
||||
## 3. Verification
|
||||
|
||||
- [x] 3.1 Add edit-mode tests that verify two or more server-side sessions can progress through login, timeout, and disconnect independently.
|
||||
- [x] 3.2 Add regression tests that confirm the client-side single-session lifecycle path still behaves as before.
|
||||
- [x] 3.3 Build the edit-mode test project and run the network-related test suite to confirm no lifecycle regressions remain.
|
||||
|
||||
## 4. Documentation
|
||||
|
||||
- [x] 4.1 Update `CodeX-TODO.md` to reflect that stage 5 lifecycle support now covers server-side multi-session management.
|
||||
- [x] 4.2 Document the new shared multi-session entry points and server-observable session states in change-related docs or code comments where needed.
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-03-27
|
||||
@@ -0,0 +1,60 @@
|
||||
## Context
|
||||
|
||||
The project already shares transport, envelope parsing, and message dispatch between Unity client and non-Unity server hosts. Stage 4 established that transport callbacks do not execute gameplay handlers inline, but session lifecycle behavior is still fragmented: transport establishment, login success, heartbeat timeout, disconnect, and reconnect intent are not modeled as separate states, and heartbeat logic is still entangled with business flow. Stage 5 needs a single host-agnostic lifecycle layer before later QoS and sync work build on unstable assumptions.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Introduce an explicit shared connection state model that distinguishes transport connection, authentication/login progress, steady-state session health, timeout, and reconnect intent.
|
||||
- Centralize heartbeat timing, timeout detection, and reconnect scheduling into a shared session manager instead of distributing them across handlers and host code.
|
||||
- Keep heartbeat infrastructure-focused: liveness detection, RTT measurement, and time sync only.
|
||||
- Allow Unity client and non-Unity server hosts to observe the same lifecycle events while keeping host-specific reactions outside the shared core.
|
||||
|
||||
**Non-Goals:**
|
||||
- Reworking message QoS or transport reliability semantics.
|
||||
- Changing the envelope protocol or replacing KCP.
|
||||
- Designing gameplay-specific reconnect UX, character resync, or rollback rules.
|
||||
- Adding final production telemetry; detailed metrics belong to a later stage.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Use an explicit shared connection state enum and session manager
|
||||
A dedicated `SessionManager` backed by a `ConnectionState` model keeps lifecycle transitions in one place and makes transport-connected, login-pending, logged-in, timed-out, reconnecting, and login-failed states observable. This is better than inferring state from scattered booleans in handlers because later features such as reconnect backoff and QoS splitting need a stable state machine boundary.
|
||||
|
||||
Alternative considered: keep lifecycle flags in `NetworkManager` and server host adapters. Rejected because it would fork client/server behavior again right after the shared-network-foundation refactor.
|
||||
|
||||
### Treat heartbeat as infrastructure signals, not business state ownership
|
||||
Heartbeat messages feed the session manager with liveness timestamps, RTT samples, and time-sync data, but they do not themselves declare login success or trigger reconnect policy. This keeps message handlers narrow and prevents hidden coupling where missing a heartbeat implicitly mutates business session state in unrelated code.
|
||||
|
||||
Alternative considered: let heartbeat handlers directly disconnect or reconnect. Rejected because it recreates the current layering problem and makes timeout policy hard to test.
|
||||
|
||||
### Make shared runtime own lifecycle orchestration, hosts own reactions
|
||||
`SharedNetworkRuntime` should compose transport, message routing, and session lifecycle so both client and server use the same lifecycle rules. Unity `NetworkManager` and `ServerNetworkHost` consume lifecycle events and decide what to do next, such as UI updates, reconnect attempts, or server-side cleanup.
|
||||
|
||||
Alternative considered: introduce separate client/server session managers. Rejected because stage five explicitly aims to share the network底层 contract and keep host differences at the adapter layer.
|
||||
|
||||
### Represent reconnect as a scheduler policy, not an immediate side effect
|
||||
Reconnect should be modeled as a transition into a reconnect-pending or reconnecting state with policy-owned timing, instead of directly restarting transport from inside a timeout callback. That makes backoff, disable/enable behavior, and tests deterministic.
|
||||
|
||||
Alternative considered: reconnect immediately inside timeout detection. Rejected because it couples timer evaluation to transport startup side effects and makes repeated failures difficult to reason about.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] Introducing a state machine can expose ambiguities in existing login/heartbeat handlers. -> Mitigation: define explicit transition sources and add tests for login success, login failure, heartbeat timeout, disconnect, and reconnect scheduling.
|
||||
- [Risk] Shared lifecycle ownership can blur the boundary between transport events and business authentication events. -> Mitigation: keep transport state inputs and login result inputs as separate session-manager APIs.
|
||||
- [Risk] Reconnect policy may require host-specific decisions later. -> Mitigation: keep policy configuration injectable and host reactions event-driven rather than hardcoding Unity-only behavior.
|
||||
- [Risk] Existing code may already assume that "connected" means "logged in". -> Mitigation: update host-facing APIs and TODO/documentation so callers consume explicit lifecycle states instead of legacy booleans.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Add shared lifecycle types (`ConnectionState`, session event model, heartbeat policy/session manager) without removing existing login/heartbeat flows yet.
|
||||
2. Route transport-connect, login-result, heartbeat-received, and timeout inputs through the new session manager.
|
||||
3. Update Unity client and server host adapters to observe lifecycle state changes from the shared runtime.
|
||||
4. Remove or simplify duplicated timeout/reconnect logic from message handlers and host code.
|
||||
5. Add edit mode tests that lock state transitions before beginning Stage 6 QoS work.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Whether the server host needs the exact same reconnect scheduling primitives as the client, or only the same state vocabulary.
|
||||
- Whether login failure should transition to `Disconnected` immediately after reporting failure, or remain in a stable `LoginFailed` state until the host decides the next action.
|
||||
- How much time-sync state should live in the session manager versus a separate clock-sync helper once Stage 6 begins.
|
||||
@@ -0,0 +1,24 @@
|
||||
## Why
|
||||
|
||||
Current networking distinguishes transport delivery from Unity threading, but it still does not distinguish transport connectivity, login success, heartbeat timeout, and reconnect flow as first-class session states. Stage 5 is needed now so client and server can share one coherent lifecycle model before QoS and sync optimization build on top of ambiguous state handling.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a shared session lifecycle module that models disconnected, transport-connected, login-pending, logged-in, timeout, reconnecting, and login-failed states explicitly.
|
||||
- Add a heartbeat policy that is limited to liveness checks, RTT measurement, and time synchronization, without owning login or reconnect decisions directly.
|
||||
- Move timeout detection, disconnect transitions, and reconnect scheduling into a shared session manager instead of leaving them in message handlers or host-specific business code.
|
||||
- Expose lifecycle state changes and session events so Unity client host and non-Unity server host can react without forking the underlying network core.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `network-session-lifecycle`: Shared connection, login, heartbeat, timeout, and reconnect state management for client and server hosts.
|
||||
|
||||
### Modified Capabilities
|
||||
- `shared-network-foundation`: The shared runtime now includes host-agnostic session lifecycle management in addition to transport and message routing.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected code: `SharedNetworkRuntime`, `MessageManager`, `NetworkManager`, `ServerNetworkHost`, login/heartbeat handlers, and new session manager/state types.
|
||||
- Affected behavior: login success no longer implies transport connect, heartbeat becomes a narrow infrastructure concern, and reconnect logic moves out of ad hoc business paths.
|
||||
- Affected tests: edit mode tests need coverage for lifecycle transitions, timeout handling, login failure, and reconnect scheduling across shared client/server runtime paths.
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Session lifecycle distinguishes transport and login state
|
||||
The shared networking core SHALL expose an explicit session lifecycle model that distinguishes transport connectivity from login/authentication success. Hosts MUST be able to observe at least disconnected, transport-connected, login-pending, logged-in, login-failed, timed-out, and reconnecting lifecycle states without inferring them from unrelated message handlers.
|
||||
|
||||
#### Scenario: Transport connect does not imply login success
|
||||
- **WHEN** the transport establishes a usable remote session but no login success message has been accepted yet
|
||||
- **THEN** the shared lifecycle reports a transport-connected or login-pending state
|
||||
- **THEN** it does not report the session as logged in
|
||||
|
||||
#### Scenario: Login success advances lifecycle independently
|
||||
- **WHEN** the client or server session manager receives a successful login/authentication result for an active transport session
|
||||
- **THEN** the shared lifecycle transitions that session into the logged-in state
|
||||
- **THEN** hosts can react to that state change without conflating it with transport establishment
|
||||
|
||||
### Requirement: Heartbeat is limited to liveness, RTT, and time sync
|
||||
The shared session lifecycle SHALL treat heartbeat traffic as infrastructure input for liveness detection, round-trip-time measurement, and clock synchronization only. Heartbeat processing MUST NOT itself own login success, login failure, or reconnect policy decisions.
|
||||
|
||||
#### Scenario: Heartbeat updates liveness and RTT only
|
||||
- **WHEN** a heartbeat response is received for an active session
|
||||
- **THEN** the session manager updates last-seen or timeout bookkeeping and RTT or clock-sync data
|
||||
- **THEN** it does not mark the session logged in solely because the heartbeat succeeded
|
||||
|
||||
#### Scenario: Missing heartbeat triggers timeout state
|
||||
- **WHEN** the configured heartbeat timeout elapses without a required heartbeat or other liveness signal
|
||||
- **THEN** the session lifecycle transitions the session into a timed-out state
|
||||
- **THEN** reconnect handling is delegated to the lifecycle reconnect policy rather than hidden inside the heartbeat handler itself
|
||||
|
||||
### Requirement: Timeout and reconnect are session-manager responsibilities
|
||||
The shared networking core SHALL manage timeout detection, disconnect transitions, and reconnect scheduling through a session-manager component rather than implementing those decisions inside business message handlers.
|
||||
|
||||
#### Scenario: Timeout produces an observable reconnect transition
|
||||
- **WHEN** a reconnect-capable host has a session that times out
|
||||
- **THEN** the session manager emits a timeout-related lifecycle transition
|
||||
- **THEN** it can subsequently move the session into a reconnecting or reconnect-pending state according to configured policy
|
||||
|
||||
#### Scenario: Login failure is distinct from transport disconnect
|
||||
- **WHEN** authentication or login fails while the transport session is still active
|
||||
- **THEN** the shared lifecycle reports a login-failed state
|
||||
- **THEN** hosts can handle that failure separately from a transport disconnect or heartbeat timeout
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Shared runtime owns host-agnostic session lifecycle orchestration
|
||||
The shared network foundation SHALL include host-agnostic session lifecycle orchestration alongside transport startup and message routing. Client and server hosts MUST be able to compose the same shared runtime with a session manager that consumes transport events, login results, and heartbeat signals without depending on Unity-specific runtime types.
|
||||
|
||||
#### Scenario: Client host composes runtime with lifecycle manager
|
||||
- **WHEN** the Unity client constructs its shared networking runtime
|
||||
- **THEN** that runtime includes shared session lifecycle management in addition to transport and message routing
|
||||
- **THEN** Unity-specific code remains responsible only for reacting to lifecycle state changes and driving host behavior
|
||||
|
||||
#### Scenario: Server host observes the same lifecycle vocabulary
|
||||
- **WHEN** a non-Unity server host composes the shared networking runtime
|
||||
- **THEN** it uses the same lifecycle state model and session-manager abstractions as the client-side shared runtime
|
||||
- **THEN** server-specific cleanup or admission behavior stays in the server host adapter rather than forking the shared core contract
|
||||
@@ -0,0 +1,19 @@
|
||||
## 1. Shared Lifecycle Model
|
||||
|
||||
- [x] 1.1 Add shared lifecycle types for connection state, session events, and heartbeat/reconnect policy configuration.
|
||||
- [x] 1.2 Implement a host-agnostic session manager that consumes transport-connected, login-result, heartbeat, timeout, and disconnect inputs.
|
||||
|
||||
## 2. Runtime Integration
|
||||
|
||||
- [x] 2.1 Extend `SharedNetworkRuntime` to compose the session manager alongside transport and message routing.
|
||||
- [x] 2.2 Update `NetworkManager` and `ServerNetworkHost` to observe explicit lifecycle state changes instead of inferring session health from ad hoc flags.
|
||||
|
||||
## 3. Heartbeat And Login Flow Cleanup
|
||||
|
||||
- [x] 3.1 Refactor login and heartbeat handlers so heartbeat only updates liveness, RTT, and time-sync state.
|
||||
- [x] 3.2 Remove timeout and reconnect decisions from business handlers and route them through session-manager policy APIs.
|
||||
|
||||
## 4. Verification And Documentation
|
||||
|
||||
- [x] 4.1 Add edit mode tests for transport-connected vs logged-in distinction, login failure, heartbeat timeout, and reconnect scheduling.
|
||||
- [x] 4.2 Update `CodeX-TODO.md` and related network docs to reflect the new lifecycle layering and stage-five completion criteria.
|
||||
@@ -0,0 +1,34 @@
|
||||
# multi-session-lifecycle Specification
|
||||
|
||||
## Purpose
|
||||
Define the shared orchestration model for hosts that manage multiple concurrent network sessions while preserving the existing per-session lifecycle vocabulary.
|
||||
|
||||
## Requirements
|
||||
### Requirement: Multi-session hosts manage per-peer lifecycle state
|
||||
The shared networking core SHALL provide a multi-session lifecycle coordinator for hosts that manage multiple concurrent remote peers. The coordinator MUST maintain distinct per-session lifecycle state keyed by remote identity rather than collapsing all peers into one runtime-level state.
|
||||
|
||||
#### Scenario: Server tracks two peers independently
|
||||
- **WHEN** a server host accepts transport activity from two different remote peers
|
||||
- **THEN** the multi-session coordinator creates or resolves two distinct managed sessions
|
||||
- **THEN** lifecycle changes for one peer do not overwrite or hide the state of the other peer
|
||||
|
||||
### Requirement: Multi-session hosts can observe and evaluate each managed session
|
||||
The multi-session lifecycle coordinator SHALL expose per-session lookup or enumeration and MUST evaluate timeout, heartbeat, login, and reconnect rules for each managed session independently using the shared session lifecycle vocabulary.
|
||||
|
||||
#### Scenario: Timeout affects only one managed session
|
||||
- **WHEN** one managed session stops receiving liveness updates while another session continues receiving heartbeat or message activity
|
||||
- **THEN** the timed-out session transitions through timeout or reconnect states according to policy
|
||||
- **THEN** the active session remains in its current healthy state
|
||||
|
||||
#### Scenario: Host can inspect current managed sessions
|
||||
- **WHEN** server-side code needs to inspect the current connection state of connected peers
|
||||
- **THEN** it can look up or enumerate managed sessions through the multi-session coordinator
|
||||
- **THEN** each entry exposes the shared session lifecycle state for that specific peer
|
||||
|
||||
### Requirement: Session removal is explicit and does not corrupt remaining peers
|
||||
The multi-session lifecycle coordinator SHALL support explicit removal or disconnection handling for one managed session without resetting unrelated sessions that remain active.
|
||||
|
||||
#### Scenario: Disconnect removes one session only
|
||||
- **WHEN** one remote peer disconnects or is evicted by the host
|
||||
- **THEN** the coordinator updates or removes that peer's managed session
|
||||
- **THEN** other managed sessions remain queryable and keep their own lifecycle state
|
||||
@@ -0,0 +1,44 @@
|
||||
# network-session-lifecycle Specification
|
||||
|
||||
## Purpose
|
||||
Define the shared session lifecycle model that separates transport connectivity, login state, heartbeat liveness, timeout detection, and reconnect scheduling for client and server hosts.
|
||||
|
||||
## Requirements
|
||||
### Requirement: Session lifecycle distinguishes transport and login state
|
||||
The shared networking core SHALL expose an explicit session lifecycle model that distinguishes transport connectivity from login/authentication success. Hosts MUST be able to observe at least disconnected, transport-connected, login-pending, logged-in, login-failed, timed-out, and reconnecting lifecycle states for each managed session without inferring them from unrelated message handlers.
|
||||
|
||||
#### Scenario: Transport connect does not imply login success
|
||||
- **WHEN** the transport establishes a usable remote session but no login success message has been accepted yet
|
||||
- **THEN** the shared lifecycle reports a transport-connected or login-pending state for that managed session
|
||||
- **THEN** it does not report the session as logged in
|
||||
|
||||
#### Scenario: Login success advances lifecycle independently
|
||||
- **WHEN** the client or server session manager receives a successful login/authentication result for an active transport session
|
||||
- **THEN** the shared lifecycle transitions that managed session into the logged-in state
|
||||
- **THEN** hosts can react to that state change without conflating it with transport establishment
|
||||
|
||||
### Requirement: Heartbeat is limited to liveness, RTT, and time sync
|
||||
The shared session lifecycle SHALL treat heartbeat traffic as infrastructure input for liveness detection, round-trip-time measurement, and clock synchronization only. Heartbeat processing MUST NOT itself own login success, login failure, or reconnect policy decisions.
|
||||
|
||||
#### Scenario: Heartbeat updates liveness and RTT only
|
||||
- **WHEN** a heartbeat response is received for an active session
|
||||
- **THEN** the session manager updates last-seen or timeout bookkeeping and RTT or clock-sync data
|
||||
- **THEN** it does not mark the session logged in solely because the heartbeat succeeded
|
||||
|
||||
#### Scenario: Missing heartbeat triggers timeout state
|
||||
- **WHEN** the configured heartbeat timeout elapses without a required heartbeat or other liveness signal
|
||||
- **THEN** the session lifecycle transitions the session into a timed-out state
|
||||
- **THEN** reconnect handling is delegated to the lifecycle reconnect policy rather than hidden inside the heartbeat handler itself
|
||||
|
||||
### Requirement: Timeout and reconnect are session-manager responsibilities
|
||||
The shared networking core SHALL manage timeout detection, disconnect transitions, and reconnect scheduling through session-manager components rather than implementing those decisions inside business message handlers. Hosts that manage multiple concurrent peers MUST apply these rules independently per managed session rather than collapsing timeout or reconnect state to the entire runtime.
|
||||
|
||||
#### Scenario: Timeout produces an observable reconnect transition
|
||||
- **WHEN** a reconnect-capable host has a session that times out
|
||||
- **THEN** the session manager emits a timeout-related lifecycle transition for that managed session
|
||||
- **THEN** it can subsequently move the session into a reconnecting or reconnect-pending state according to configured policy
|
||||
|
||||
#### Scenario: Login failure is distinct from transport disconnect
|
||||
- **WHEN** authentication or login fails while the transport session is still active
|
||||
- **THEN** the shared lifecycle reports a login-failed state for that managed session
|
||||
- **THEN** hosts can handle that failure separately from a transport disconnect or heartbeat timeout
|
||||
@@ -1,7 +1,7 @@
|
||||
# shared-network-foundation Specification
|
||||
|
||||
## Purpose
|
||||
Define the shared transport and message-routing foundation that both client and server hosts use without depending on Unity-specific runtime host classes.
|
||||
Define the shared transport, session-lifecycle, and message-routing foundation that both client and server hosts use without depending on Unity-specific runtime host classes.
|
||||
|
||||
## Requirements
|
||||
### Requirement: Shared network core is host-agnostic
|
||||
@@ -37,3 +37,16 @@ The shared client/server foundation SHALL preserve the existing `ITransport` sen
|
||||
- **WHEN** a client host sends a business message through the shared core to a server host using the shared core
|
||||
- **THEN** the message is encoded using the same envelope contract on the client side
|
||||
- **THEN** the server host decodes and routes it through the shared message-routing layer without a host-specific protocol fork
|
||||
|
||||
### Requirement: Shared runtime owns host-agnostic session lifecycle orchestration
|
||||
The shared network foundation SHALL include host-agnostic session lifecycle orchestration alongside transport startup and message routing. Client and server hosts MUST be able to compose the shared foundation with session orchestration that consumes transport events, login results, and heartbeat signals without depending on Unity-specific runtime types, while supporting both single-session client composition and multi-session server composition.
|
||||
|
||||
#### Scenario: Client host composes runtime with single-session lifecycle manager
|
||||
- **WHEN** the Unity client constructs its shared networking runtime
|
||||
- **THEN** that runtime includes shared session lifecycle management for its single remote session in addition to transport and message routing
|
||||
- **THEN** Unity-specific code remains responsible only for reacting to lifecycle state changes and driving host behavior
|
||||
|
||||
#### Scenario: Server host composes shared foundation with multi-session orchestration
|
||||
- **WHEN** a non-Unity server host constructs the runtime networking stack for multiple remote peers
|
||||
- **THEN** it uses the shared transport and message-routing foundation together with shared multi-session lifecycle orchestration
|
||||
- **THEN** server-specific cleanup, admission, and gameplay reactions stay in the server host adapter rather than forking the shared lifecycle contract
|
||||
|
||||
Reference in New Issue
Block a user