一尘不染

从Controller调用SignalR Core Hub方法

c#

如何从Controller调用SignalR Core Hub方法?
我将ASP.NET Core 2.0与Microsoft.AspNetCore.SignalR(1.0.0-alpha2-final)一起使用。

我有与Excel,SolidEdge和Excel通信的Windows服务…完成操作后,它将请求发布到ASP.NET
Core应用程序中的控制器。现在,我需要通知所有与SignalR连接到服务器的客户端,外部程序已完成某些任务。
我无法更改窗口服务的工作方式。(无法从窗口服务连接到SignalR)。
我找到了许多适用于旧SignalR(GlobalHost.ConnectionManager.GetHubContext)的解决方案,但发生了很大变化,这些解决方案不再起作用。

我的控制器:

[Route("API/vardesigncomm")]
public class VarDesignCommController : Controller
{
    [HttpPut("ProcessVarDesignCommResponse/{id}")]
    public async Task<IActionResult> ProcessVarDesignCommResponse(int id)
    {
        //call method TaskCompleted in Hub !!!! How?

        return new JsonResult(true);
    }
}

我的中心:

public class VarDesignHub : Hub
{
    public async Task TaskCompleted(int id)
    {
        await Clients.All.InvokeAsync("Completed", id);
    }
}

阅读 896

收藏
2020-05-19

共1个答案

一尘不染

解决方案1

另一种可能性是将HubContext注入到控制器中,例如:

public VarDesignCommController(IHubContext<VarDesignHub> hubcontext)
{
    HubContext = hubcontext;
    ...
}

private IHubContext<VarDesignHub> HubContext
{ get; set; }

那你也可以打电话

await this.HubContext.Clients.All.InvokeAsync("Completed", id);

但是随后您将在所有客户端上直接调用方法。

解决方案2

您还可以使用类型化的集线器:简单创建一个接口,在其中定义服务器可以在客户端上调用的方法:

public interface ITypedHubClient
{
    Task BroadcastMessage(string name, string message);
}

从集线器继承:

public class ChatHub : Hub<ITypedHubClient>
{
    public void Send(string name, string message)
    {
        Clients.All.BroadcastMessage(name, message);
    }
}

将键入的hubcontext注入到控制器中,并使用它:

[Route("api/demo")]
public class DemoController : Controller
{
    IHubContext<ChatHub, ITypedHubClient> _chatHubContext;
    public DemoController(IHubContext<ChatHub, ITypedHubClient> chatHubContext)
    {
        _chatHubContext = chatHubContext;
    }

    // GET: api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        _chatHubContext.Clients.All.BroadcastMessage("test", "test");
        return new string[] { "value1", "value2" };
    }
}
2020-05-19