有没有办法避免在 HubConnection class 中使用魔法字符串

Is there a way to avoid using magic strings with the HubConnection class

我在服务器上有一个强类型集线器:

public Foo : Hub<Bar> {}

Bar 应该是一个接口,包括客户端可用的方法。但这只解决了问题的一半(服务器的一半)。在客户端,我仍然必须使用魔术字符串来定义调用 Bar:

方法的处理程序
 hubConnection.On<int>("MethodInsideBar", param => DoSomething(param));

有没有办法避免这样做?难道不应该有一种方法来实现 Bar 客户端和 link 从服务器到该实现的调用吗?

On the client side, I still have to use magic strings to define handlers for calls to the methods of Bar:

hubConnection.On<int>("MethosInsideBar", param => DoSomething(param)); 

Is there a way to avoid doing this ? Shouldn't there be a way to implement Bar client side and link the calls from the server to that implementation ?

据我所知,强类型集线器只适用于服务器端,我们可以inject the strongly-typed HubContext在控制器中,然后调用集线器方法。它可以防止方法名称拼写错误或从客户端丢失。

在client端,我们仍然需要使用Invoke方法调用hubs上的public方法,定义一个方法使用HubConnection的on方法来接收来自中心的消息。

当从客户端调用public集线器方法时,如果你想使用强类型集线器,你可以将强类型集线器上下文注入控制器,然后使用JQuery Ajax 调用控制器的操作方法,然后使用强类型集线器方法。参考这个线程:.

您可以使用 SignalR.Strong NuGet

示例代码:
Foo.cs

public interface IBar
{
    Task MethodInsideBar(int n);
}
public class Foo : Hub<IBar> {}

Client.cs:

public class MySpoke : IBar
{
    public Task MethodInsideBar(int n)
    {
        // 
        return Task.CompletedTask;
    }
}

var conn = new SignalR.Client.HubConnection()
    .WithUrl("http://localhost:53353/MyHub")
    .Build();

await conn.StartAsync();

var registration = conn.RegisterSpoke<IBar>(new MySpoke())

BlazorPage.razor

@using Microsoft.AspNetCore.SignalR.Client
@using SignalR.Strong
@inject NavigationManager Nav
@implements IBar

@code {
    private HubConnection? hubConnection;

    public Task MethodInsideBar(int n)
    {
        // 
        return Task.CompletedTask;
    }

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Nav.ToAbsoluteUri("/foo"))
            .WithAutomaticReconnect()
            .Build();

        await hubConnection.StartAsync();

        hubConnection.RegisterSpoke<IBar>(this);

        await base.OnInitializedAsync();
    }
}

server.cs

public class FooBar
{
    private readonly IHubContext<Foo, IBar>? _hubContext;

    // dependency injected IHubContext
    public FooBar(IHubContext<Foo, IBar>? hubContext)
    {
        _hubContext = hubContext;
    }

    public void CallBar(int n)
    {
        _hubContext?.Clients.All.MethodInsideBar(n);
    }
}