# SignalR Server Server-side SignalR hub infrastructure: method dispatch, session management, broadcast, and diagnostics. Source: `SignalRs/` in this project. > For client-side transport (tags, wire protocol, client base) see `AyCode.Services/docs/SIGNALR.md`. > For the DataSource collection see `SIGNALR_DATASOURCE.md`. ## Server Processing ``` 6. OnReceiveMessage(tag, requestId, signalParams, SignalData data) 7. Extract parameterBytes from signalParams.Parameters 8. DynamicMethodRegistry.GetMethodByMessageTag(tag) <- ConcurrentDictionary lookup 9. signalParams.GetParameterValues(paramInfos): |- byte[] -> BinaryTo() (cached) |- Per-element: byte[][i].BinaryTo(paramInfos[i].ParameterType) |- Trailing defaults auto-filled |- Hub validates: missing required params throw ArgumentException '- NOTE: BinaryTo only -- JSON param deserialization not supported (needs JsonTo + project ref) 10. MethodInfo.InvokeMethod(instance, params) <- unwraps Task/ValueTask 11. CreateResponseMessage(tag, Success, result) <- Binary serialize payload -> byte[] 12. SendMessageToClient(caller, tag, message, requestId): |- Extract signalParams { Status, DataSerializerType } + SignalData from message '- caller.OnReceiveMessage(tag, requestId, signalParams, SignalData) (metadata + payload as separate args -- no envelope serialization) 13. If SendToOtherClientType != None: '- SendMessageToOthers(sendToOtherClientTag, result) <- uses sendToOtherClientTag, not messageTag ``` ## Dynamic Method Dispatch See also: `AyCode.Models.Server/DynamicMethods/README.md` ### Server-Side Lookup ``` 1. OnReceiveMessage(tag=100, requestId, signalParams, SignalData data) 2. DynamicMethodRegistry.GetMethodByMessageTag(100) |- Check static ConcurrentDictionary cache |- Hit? -> find instance of cached Type from registered instances |- Miss? -> scan all registered instances' methods for [SignalR(100)] | cache the result (including negative = null) '- Return (instance, methodInfoModel) or null 3. AcMethodInfoModel contains: |- MethodInfo (the method to invoke) |- SignalRAttribute (tag, sendToOtherClientTag, sendToOtherClientType) '- ParamInfos[] (ParameterInfo for deserialization) ``` The `DynamicMethodRegistry` uses a static `ConcurrentDictionary` for the global tag->method cache. ### Registration The hub registers service instances during initialization: ```csharp DynamicMethodRegistry.Register(myService); // scans [SignalR(tag)] methods lazily DynamicMethodRegistry.Register(anotherService); ``` Reflection runs lazily per tag on first request, then results are cached statically. ## Session Management `AcSessionService` tracks connected clients: ```csharp ConcurrentDictionary Sessions ``` `IAcSessionItem` requires `SessionId` property. Used for targeting messages to specific users/connections. ## Broadcast Service `AcSignalRSendToClientService` provides server-push methods: | Method | Target | |--------|--------| | `SendMessageToAllClients` | All connected | | `SendMessageToConnection(connectionId)` | Single connection | | `SendMessageToUser(userId)` | User (all connections) | | `SendMessageToUsers(userIds)` | Multiple users | All messages serialized to `SignalData` payload + `SignalParams` metadata (Parameters=null for server->client push) -> sent as separate hub arguments via `OnReceiveMessage` (no envelope wrapping). Server wraps `byte[]` in non-pooled `SignalData`; client receives as `ArrayPool`-backed `SignalData` via `AyCodeBinaryHubProtocol`. ## Hub Events - `OnConnectedAsync()` -- log connection - `OnDisconnectedAsync(exception)` -- log disconnection, cleanup session ## Diagnostics Enable with `AcWebSignalRHubBase.EnableBinaryDiagnostics = true`. Logs: hex dump (500 byte sample), header parsing (version, marker), property count + names via VarUInt reading. `SignalResponseDataMessage.DiagnosticLogger` -- per-response logging: target type info, property list, inheritance chain, hex dump. Uses `SignalData.Span` for zero-alloc diagnostics. ## Key Source Files | Component | Path | |-----------|------| | Hub base | `SignalRs/AcWebSignalRHubBase.cs` | | Session service | `SignalRs/AcSessionService.cs` | | Broadcast service | `SignalRs/AcSignalRSendToClientService.cs` | | Logger hub | `SignalRs/AcLoggerSignalRHub.cs` | | Tracking helpers | `SignalRs/TrackingItemHelpers.cs` | | Dynamic dispatch | `AyCode.Models.Server/DynamicMethods/AcDynamicMethodRegistry.cs` |