Skip to content

Getting Started with SignalRGen ​

SignalRGen simplifies working with SignalR in .NET applications by generating strongly typed clients from simple interface definitions. This guide will walk you through creating a basic SignalR communication setup backed by SignalRGen.

TIP

If you want a more elaborate rundown, head over to the detailed tutorial.

Overview ​

We'll build a simple ping-pong example with:

  • A server that responds to ping messages
  • A client that sends pings and receives pongs
  • A shared interface defining our contract

Quick Installation ​

Add SignalRGen to your shared interface project:

shell
dotnet add package SignalRGen

Define Your SignalR Interface ​

Create an interface that describes your Hub's communication:

csharp
using SignalRGen.Abstractions;
using SignalRGen.Abstractions.Attributes;

namespace MySharedInterface;

[HubClient(HubUri = "ping-pong")]
public interface IPingPongHubContract : IBidirectionalHub<IPingPongServerToClient, IPingPongClientToServer>
{
}

public interface IPingPongServerToClient
{
    Task Pong(string answer);
}

public interface IPingPongClientToServer
{
    Task Ping(string message);
}

That's it! SignalRGen will automatically generate the client implementation.

Server-Side Implementation ​

Create a Hub class that inherits from both Hub<IPingPongHub> and IPingPongClientToServer:

csharp
public class PongHub : Hub<IPingPongServerToClient>, IPingPongClientToServer
{
    private readonly ILogger<PongHub> _logger;

    public PongHub(ILogger<PongHub> logger)
    {
        _logger = logger;
    }
    
    public Task Ping(string message)
    {
        _logger.LogInformation("Received Ping: {Message}", message);
        return Clients.All.Pong("Hey, here is the server talking!");
    }
}

Remember to register your Hub in Program.cs:

csharp
app.MapHub<PongHub>($"/{PingPongHubContractClient.HubUri}");

Client-Side Usage ​

Register the Hub ​

Configure the hub in your client's Program.cs:

csharp
builder.Services.AddSignalRHubs(c => c.HubBaseUri = new Uri("http://localhost:5160"))
    .WithPingPongHubContractClient();

Use the Generated Client ​

The generated PingPongHubContractClient class can now be injected into your services:

csharp
public class Worker : IHostedService
{
    private readonly ILogger<Worker> _logger;
    private readonly PingPongHubContractClient _hub;  // Use the generated class, not the interface

    public Worker(ILogger<Worker> logger, PingPongHub hub)
    {
        _logger = logger;
        _hub = hub;
    }
    
    public Task StartAsync(CancellationToken cancellationToken)
    {
        // Subscribe to server-to-client events
        _hub.OnPong += answer => {
            _logger.LogInformation("Received Pong: {Answer}", answer);
            return Task.CompletedTask;
        };

        return _hub.StartAsync(cancellationToken: cancellationToken);
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return _hub.StopAsync(cancellationToken: cancellationToken);
    }
}

Call Server Methods ​

Invoke client-to-server methods like this:

csharp
app.MapGet("/ping", async ([FromServices] PingPongHubContractClient hub) =>
{
    await hub.InvokePingAsync("Hello from the client!");
});

Key Points to Remember ​

  • The interface (IPingPongHubContractClient) defines the contract between client and server
  • Methods in the TServer interface are server-to-client callbacks
  • Methods in the TClient interface are client-to-server calls
  • Use the generated class (PingPongHubContractClient) in your client code, not the interface
  • The server implements a Hub by implementing the TClient interface and inherits from Hub<TServer>

Complete Example ​

For the full step-by-step example including project setup, see our detailed tutorial.