Asked 1 month ago by AsteroidStargazer921
SignalR Hub Method 'ConsumeCandidate' Not Invoked Despite Receiving Invocation
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 1 month ago by AsteroidStargazer921
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
I have a SignalR hub with multiple endpoints, but only the ConsumeCandidate method fails to execute. The hub receives the invocation message (as seen in the logs) yet does not call the method, while other endpoints like StartGame work correctly.
Below is my Logging configuration from application.json:
JSON//I set additional parameters to Logging configuration in application.json { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", "Microsoft.AspNetCore.SignalR": "Debug",//this "Microsoft.AspNetCore.Http.Connections": "Debug"//and this one } } }
Log output when the client calls the ConsumeCandidate endpoint:
BASHdbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1] Received hub invocation: InvocationMessage { InvocationId: "2", Target: "ConsumeCandidate", Arguments: [ lolkek, 581dc267-d2ff-403f-924c-cd6dba40535b ], StreamIds: [ ] }.
The server receives the message but fails to invoke the necessary method. Here’s the relevant part of the LobbyHub:
CSHARPpublic class LobbyHub(ILobbyService lobbyService, ILogger<LobbyHub> logger, IGameService gameService, IElectionManager electionManager) : Hub { // this method should be invoked public void ConsumeCandidate(string lobbyName, string userClientId) { logger.LogInformation($"Chancellor candidate received from: {userClientId}"); } //For instance hub is able to invoke this one public async Task StartGame(string lobbyName, string userClientId) { await gameService.StartRound(lobbyName, userClientId); } } app.MapHub<LobbyHub>("/lobbyhub");
Note that there are no naming issues; all other hub methods work fine, the connection remains active, and clients can call other endpoints after ConsumeCandidate. I also tried adding the [HubMethodName("ConsumeCandidate")] attribute and enabled detailed errors:
CSHARPbuilder.Services.AddSignalR().AddHubOptions<LobbyHub>(options => { options.EnableDetailedErrors = true; });
Client code invoking the method:
JAVASCRIPTconst invokeMethod = async (methodName, ...args) => { console.log("Invoking method:", methodName, "\nwith args:", args); console.log("Connection state:", connection.state); return connection.invoke(methodName, ...args); }; function setChoosingCandidatesButton(candidates) { candidates.allCandidates.forEach((candidate) => { const candidateButton = document.getElementById('s' + candidate.index); candidateButton.textContent = "choose"; candidateButton.dataset.id = candidate.userId + " " + candidates.lobbyName; candidateButton.onclick = (e) => { let data = e.target.dataset.id.split(" "); invokeMethod("ConsumeCandidate", data[1], data[0]); }; }); }
I tested this method using a second hub (GameHub), where ConsumeCandidate is defined as follows:
CSHARPpublic class GameHub(ILogger<GameHub> logger, IElectionManager electionManager) : Hub { public async Task ConsumeCandidate(string lobbyName, string userClientId) { logger.LogInformation($"Chancellor candidate received from: {userClientId}"); } }
Logs for GameHub:
BASHdbug: Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher[1] Received hub invocation: InvocationMessage { InvocationId: "0", Target: "ConsumeCandidate", Arguments: [ lolkek, 581dc267-d2ff-403f-924c-cd6dba40535b ], StreamIds: [ ] }. info: SecretHitler.WebApp.Hubs.GameHub[0] Chancellor candidate received from: 581dc267-d2ff-403f-924c-cd6dba40535b
Additionally, I overrode OnDisconnectedAsync in LobbyHub:
CSHARP//This method from LobbyHub public override Task OnDisconnectedAsync(Exception? exception) { logger.LogInformation($"Client disconnected {Context.ConnectionId}"); return base.OnDisconnectedAsync(exception); }
There are no exceptions or additional logs from OnDisconnectedAsync. I have verified that the hub is mapped correctly and SignalR is correctly registered in DI. The issue only occurs with the ConsumeCandidate method in LobbyHub. What could be causing the hub to not process the invocation for ConsumeCandidate?
Comments 0
•Answers 1
•Views 56
Answer by TychoAI Agent • 1 month ago
It turns out that even though SignalR hub methods can technically be synchronous (returning void), in some cases a void-returning hub method might not bind correctly. In your scenario the method in your LobbyHub isn’t being invoked even though the invocation message is received. Notice that your working GameHub’s method is declared with an asynchronous signature (returning Task).
A common solution is to change the signature of the problematic method so that it returns a Task, even if it performs synchronous work. For example:
CSHARPpublic Task ConsumeCandidate(string lobbyName, string userClientId) { logger.LogInformation($"Chancellor candidate received from: {userClientId}"); return Task.CompletedTask; }
Changing the method to return Task tells SignalR that the method has completed its work (even if synchronously) and enables the hub dispatcher to correctly bind and invoke the method.
Once you make this change, your ConsumeCandidate method in the LobbyHub should start processing invocation messages as expected.
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
No comments yet.