【问题标题】:Is there a way to avoid using magic strings with the HubConnection class有没有办法避免在 HubConnection 类中使用魔术字符串
【发布时间】:2021-02-09 23:23:48
【问题描述】:
我在服务器上有一个强类型集线器:
public Foo : Hub<Bar> {}
Bar 应该是一个接口,包括客户端可用的方法。但这只能解决问题的一半(服务器的一半)。在客户端,我仍然必须使用魔术字符串来定义处理程序以调用Bar 的方法:
hubConnection.On<int>("MethodInsideBar", param => DoSomething(param));
有没有办法避免这样做?不应该有一种方法来实现Bar 客户端并将来自服务器的调用链接到该实现吗?
【问题讨论】:
标签:
signalr
signalr-hub
signalr.client
asp.net-core-signalr
【解决方案1】:
您可以使用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);
}
}
【解决方案2】:
在客户端,我还是要用魔术字符串来定义
调用 Bar 方法的处理程序:
hubConnection.On<int>("MethosInsideBar", param => DoSomething(param));
有没有办法避免这样做?不应该
有一种方法可以实现 Bar 客户端并链接来自的调用
该实现的服务器?
据我所知,强类型集线器只适用于服务器端,我们可以在控制器中inject the strongly-typed HubContext,然后调用集线器方法。它可以防止客户端的方法名称拼写错误或丢失。
在客户端,我们仍然需要使用Invoke方法调用hub上的公共方法,并使用HubConnection的on方法定义一个方法来接收来自hub的消息。
从客户端调用公共 hub 方法时,如果要使用强类型集线器,可以将强类型集线器上下文注入控制器,然后使用 JQuery Ajax 调用控制器的 action 方法,然后使用强类型集线器方法.参考这个帖子:SignalR - Call statically typed hub from Context。