# SignalR — TODO ## Priority legend - **P0** blocker · **P1** important · **P2** nice-to-have · **P3** idea --- ## SIG-T-1: Diagnose first-call null in PostDataAsync **Priority:** P2 · **Type:** Investigation · **Related:** `SIGNALR_ISSUES.md#issue-02` Reproduce the `GetProductDtos_80`-style first-call null. Add trace logs to `PostDataAsync` awaiter path and `OnReceiveMessage → pending request` dictionary lookup. Verify `requestId → Task` correlation on the very first chunked response of a fresh connection. ## SIG-T-2: Document asymmetric send/receive capability **Priority:** P1 · **Type:** Docs Current behaviour: sender selects `BinaryProtocolMode` independently; receiver detects the wire format from the first byte (`CHUNK_START=200` → chunked path; else non-chunked). This means client and server can run DIFFERENT `ProtocolMode` settings independently — a core feature amplifying interoperability. Document in `../SIGNALR_BINARY_PROTOCOL/README.md` as a dedicated "Asymmetric send/receive contract" section. Key selling points: - WASM client + AsyncSegment server → works (WASM downgrades send, receives chunked happily) - Third-party client on NuGet can pick any mode → server doesn't care - Gradual mode rollouts possible (no synchronized deploy) ## SIG-T-3: Code-level guard for FlushTimeout < ClientTimeoutInterval **Priority:** P2 · **Type:** Feature `AcBinaryHubProtocolOptions.Validate()` currently documents (in XML doc) that `FlushTimeout` should be less than the SignalR `HubOptions.ClientTimeoutInterval`, but there is no code-level check. Add validation at protocol registration time — if both options are resolvable from the DI scope, verify the constraint and emit a startup warning (or throw, pending decision). ## SIG-T-4: `BinaryProtocolMode.Auto` — adaptive send-mode **Priority:** P3 · **Type:** Feature · **Related:** `../SIGNALR_BINARY_PROTOCOL/SIGNALR_BINARY_PROTOCOL_TODO.md#sbp-t-3` Design: on first received message, inspect first byte to determine peer's send format. On subsequent sends, match it (subject to local-platform constraints, e.g. WASM never actually sends AsyncSegment). Per-`HubConnection` state. Optional upfront handshake-extension negotiation as an alternative — see wire-level TODO. ## SIG-T-5: Server-side NopCommerce plugin — expose `AcBinaryHubProtocolOptions` via appsettings **Priority:** P2 · **Type:** Consumer refactor · **Related:** `SIGNALR_ISSUES.md#sig-i-7`, `../../../AyCode.Core/docs/LOGGING/LOGGING_TODO.md#log-t-11` Bind `AcBinaryHubProtocolOptions` from `appsettings.json` instead of hardcoding `ProtocolMode` and constructing a manual `Logger` instance in `PluginNopStartup.cs`. This sibling task is paired with LOGGING_TODO.md#log-t-11 (same plugin, logger-setup migration) — best landed in one commit. ### Target diff ```csharp // In PluginNopStartup.ConfigureServices, BEFORE AddSignalR(...): // 1. Bind Protocol options from appsettings.json services.Configure(configuration.GetSection("AyCode:SignalR:Protocol")); // 2. AddSignalR + AddAcBinaryProtocol — drop the inline Action entirely services.AddSignalR(hubOptions => { /* unchanged */ }) .AddAcBinaryProtocol(); // ← BuildProtocol auto-resolves IOptions + ILogger from DI ``` ### Appsettings.json addition (sibling to `AyCode:Logger`) ```json { "AyCode": { "Logger": { "AppType": "Server", "LogLevel": "Debug" }, "SignalR": { "Protocol": { "ProtocolMode": "AsyncSegment", "BufferSize": 4096, "WaitForFlush": true, "FlushTimeout": "00:00:10" } } } } ``` ### Consequences / checklist - [ ] `new Logger(...)` line removed from SignalR registration → server-side logger now goes through the DI factory (see LOGGING_TODO.md#log-t-11). - [ ] Per-deploy tuning possible without recompile: switching `ProtocolMode` for diagnostics, extending `FlushTimeout` for slow links, adjusting `BufferSize` for different Kestrel slab sizes. - [ ] `Name` stays at `"acbinary"` default — changing it would break wire-level compat with existing clients. - [ ] `AcBinaryHubProtocolOptions.Validate()` still runs — invalid config (e.g. `ProtocolMode=AsyncSegment` on a WASM server, which is impossible here but hypothetically) throws at startup. - [ ] Plugin doc correction: `Nop.Plugin.Misc.AIPlugin/docs/SIGNALR/README.md:22` — the legacy `services.AddSingleton(new AcBinaryHubProtocol())` line must be replaced with the real registration. Cross-ref the new `AyCode:SignalR:Protocol` section here. ### Why this belongs in AyCode.Services (framework layer) docs The gap is consumer-level, but the canonical "server-side registration recipe" is a FRAMEWORK responsibility — LOGGING.md already shows it for the logger side. Adding a matching recipe to `../SIGNALR_BINARY_PROTOCOL/README.md#Registration in Program.cs → Server` would prevent the next consumer from making the same mistake. That doc update is part of this TODO's acceptance criteria. ## SIG-T-6: Delete legacy `[Obsolete]` JSON-in-Binary wrappers **Priority:** P3 · **Type:** Cleanup · **Related:** `../../../AyCode.Core/docs/XCUT/XCUT_ISSUES.md#xcut-i-1` (closed canonical), `../../../AyCode.Core/docs/BINARY/BINARY_TODO.md#bin-t-1` (closed) Now that XCUT-I-1 / BIN-T-1 have landed and the wire format no longer uses JSON-in-Binary, the `[Obsolete]` wrapper types in `IAcSignalRHubClient.cs:60-111` can be deleted: - `SignalPostJsonMessage` - `SignalPostJsonDataMessage` - `SignalPostMessage` - `ISignalPostMessage` **Gate:** verify external consumer projects no longer reference these types — compile-time scan across the workspace + dependent solutions before removal. **Acceptance:** all four obsolete types deleted from `IAcSignalRHubClient.cs`; no CS0618 warnings in any consumer build; remaining doc/glossary mentions either deleted or rewritten as historical references.