有没有办法避免在 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);
}
}
我在服务器上有一个强类型集线器:
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);
}
}