Skip to content

Latest commit

 

History

History
305 lines (229 loc) · 7.41 KB

File metadata and controls

305 lines (229 loc) · 7.41 KB

UiRealTimeCommunicator Usage Guide

This guide provides detailed, end-to-end examples for using UiRealTimeCommunicator in real applications.

Table of Contents

Server Setup

Install the package:

dotnet add package UiRealTimeCommunicator

Register the services and middleware:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddUiRealTimeCommunicator();

var app = builder.Build();

app.UseUiRealTimeCommunicator();

app.Run();

Define Hubs

Hubs are marker classes that identify a communication channel.

public class WeatherHub : IUiRtcHub
{
}

By default, the hub name is the class name (WeatherHub). You can override it with [UiRtcHub] (see Custom Hub and Method Names).

Server-to-Client Messaging (Sender Contracts)

Define a sender contract interface. Each method becomes a TypeScript subscription.

public interface WeatherSender : IUiRtcSenderContract<WeatherHub>
{
    Task WeatherForecast(WeatherForecastModel forecast);
    Task WeatherAlert(WeatherAlertModel alert);
}

Use the sender contract in your services:

public class WeatherService(IUiRtcSenderService senderService)
{
    public async Task PublishForecastAsync(WeatherForecastModel model)
    {
        await senderService.Send<WeatherSender>().WeatherForecast(model);
    }

    public async Task PublishAlertAsync(WeatherAlertModel model)
    {
        await senderService.Send<WeatherSender>().WeatherAlert(model);
    }
}

Client-to-Server Messaging (Handlers)

Handlers receive messages from the client. Each handler class becomes a TypeScript communication method.

[UiRtcMethod("GetWeatherForecast")]
public class GetWeatherForecastHandler : IUiRtcHandler<WeatherHub, WeatherForecastRequestModel>
{
    public async Task ConsumeAsync(WeatherForecastRequestModel model)
    {
        // Handle request from client
    }
}

Handlers with Context

If you need connection IDs or other SignalR context, use IUiRtcContextHandler:

public class GetWeatherWithContextHandler : IUiRtcContextHandler<WeatherHub, WeatherForecastRequestModel>
{
    public async Task ConsumeAsync(WeatherForecastRequestModel model, IUiRtcProxyContext context)
    {
        var connectionId = context.ConnectionId;
        // Use connectionId if needed
    }
}

Connection Lifecycle Events

Implement IUiRtcConnection<THub> to receive connection events:

public class WeatherConnectionHandler : IUiRtcConnection<WeatherHub>
{
    public Task OnConnectedAsync(string connectionId)
    {
        // Handle client connection
        return Task.CompletedTask;
    }

    public Task OnDisconnectedAsync(string connectionId, Exception? exception)
    {
        // Handle client disconnection
        return Task.CompletedTask;
    }
}

Sending to Specific Connections

You can target specific connections when sending messages:

public class WeatherService(IUiRtcSenderService senderService)
{
    public async Task SendToSpecificClientAsync(string connectionId, WeatherForecastModel model)
    {
        await senderService.Send<WeatherSender>(connectionId).WeatherForecast(model);
    }

    public async Task SendToMultipleClientsAsync(string[] connectionIds, WeatherAlertModel model)
    {
        await senderService.Send<WeatherSender>(connectionIds).WeatherAlert(model);
    }
}

Model Generation

Mark models with [TranspilationSource] so they are generated into TypeScript.

[TranspilationSource]
public class WeatherForecastModel
{
    public required string City { get; set; }
    public required double Temperature { get; set; }
    public string? Summary { get; set; }
}

[TranspilationSource]
public class WeatherAlertModel
{
    public required string Level { get; set; }
    public required string Message { get; set; }
}

[TranspilationSource]
public class WeatherForecastRequestModel
{
    public required string City { get; set; }
}

TypeScript Client Usage

Install SignalR:

npm install @microsoft/signalr

Initialize connections:

import { uiRtc } from "./communication/contract";

await uiRtc.initAsync({
  serverUrl: "http://localhost:5064/",
  activeHubs: "All",
});

Send messages to the server:

import { uiRtcCommunication, WeatherForecastRequestModel } from "./communication/contract";

await uiRtcCommunication.Weather.GetWeatherForecast({
  city: "Kharkiv",
} as WeatherForecastRequestModel);

Subscribe to messages from the server:

import { uiRtcSubscription, WeatherForecastModel } from "./communication/contract";

const subscription = uiRtcSubscription.Weather.WeatherForecast(
  (data: WeatherForecastModel) => {
    console.log("Forecast:", data);
  }
);

// Unsubscribe when needed
subscription.unsubscribe();

Multiple Hubs

You can define multiple hubs and use them independently.

public class ChatHub : IUiRtcHub { }
public class WeatherHub : IUiRtcHub { }

public interface ChatSender : IUiRtcSenderContract<ChatHub>
{
    Task Message(ChatMessageModel message);
}

public interface WeatherSender : IUiRtcSenderContract<WeatherHub>
{
    Task Forecast(WeatherForecastModel forecast);
}

TypeScript initialization can target all hubs or specific ones:

await uiRtc.initAsync({
  serverUrl: "http://localhost:5064/",
  activeHubs: ["Chat", "Weather"],
});

Custom Hub and Method Names

Use attributes to customize hub and method names.

[UiRtcHub("Weather")]
public class WeatherHub : IUiRtcHub { }

[UiRtcMethod("GetForecast")]
public class GetWeatherHandler : IUiRtcHandler<WeatherHub, WeatherForecastRequestModel>
{
    public Task ConsumeAsync(WeatherForecastRequestModel model)
    {
        return Task.CompletedTask;
    }
}

public interface WeatherSender : IUiRtcSenderContract<WeatherHub>
{
    [UiRtcMethod("Forecast")]
    Task SendForecast(WeatherForecastModel forecast);
}

Troubleshooting

Hub or method not found in TypeScript output

  • Ensure hub classes implement IUiRtcHub
  • Ensure handler classes implement IUiRtcHandler<THub> or IUiRtcHandler<THub, TModel>
  • Ensure sender contracts implement IUiRtcSenderContract<THub>

Model types show as any

  • Ensure models are marked with [TranspilationSource]
  • Ensure model types are in the project being transpiled

Connection errors on the client

  • Check serverUrl includes the correct base URL
  • Ensure you call uiRtc.initAsync() before sending or subscribing

Generate TypeScript Code

Install the generator tool:

dotnet tool install --global UiRealTimeCommunicator.TypeScriptGenerator

Generate code:

dotnet-uirtc -p "./YourProject/YourProject.csproj" -o "./frontend/src/communication/contract.ts"

If the output path is a directory, the file contract.ts is created automatically.