如何在SignalR alpha for NET Core 2.0中向所有客户端发送消息?

3
我正在使用 signalR 1.0.0-alpha2-final,并希望向所有连接的客户端发送消息。
我已经以这个教程为起点:this tutorial
我的 RulesHub 继承自 Hub:
[EnableCors("MyPolicy")]
public class RulesHub : Hub
{
    private readonly IRuleService _ruleService;

    public RulesHub(IRuleService ruleService)
    {
        _ruleService = ruleService;
    }

    public Task Send()
    {
        var rules = _ruleService.RulesMonitoring();
        return Clients.All.InvokeAsync("SendRules", rules);
    }
}

在前端,我有以下代码来连接到Hub:

let connection = new signalR.HubConnection(rulesMonitorUrl);

connection.on('SendRules', function(data:any){
    console.log(data);
});

在连接了一个客户端之后,我从这个控制器调用Send方法:

[EnableCors("MyPolicy")]
Route("api/[controller]")]
public class MyController : Controller
{
    private readonly IMyService _myService;
    private RulesHub _rulesHub;

    public MyController(IMyService myService, IRuleService ruleService)
    {
        _myService = myService;
        _rulesHub = new RulesHub(ruleService);
    }

    [HttpPost]
    public void Post([FromBody]MyClass myClass)
    {
        _myService.Add(myClass);
        _rulesHub.Send();
    }
}

但是代码行return Clients.All.InvokeAsync("SendRules", rules);会导致以下异常信息:

System.NullReferenceException:“对象引用未设置到对象实例。”

Microsoft.AspNetCore.SignalR.Hub.Clients返回了null。

我读到在ASP.NET中应该使用类似于IHubContext context = GlobalHost.ConnectionManager.GetHubContext("MyChatHub");的语句,但在这个版本中无法使用。

有什么想法吗?

1个回答

4
这是一个重复的问题: 从控制器调用SignalR Core Hub方法

您不应该自行创建Hub实例。只需将其注入到您的控制器中即可,示例如下:
[EnableCors("MyPolicy")]
Route("api/[controller]")]
public class MyController : Controller
{
    private readonly IMyService _myService;
    private  IHubContext<RulesHub> _rulesHubContext;    

    public MyController(IMyService myService, IRuleService ruleService, IHubContext<RulesHub > rulesHubContext)
    {
        _myService = myService;
        _rulesHubContext = rulesHubContext;
    }

    [HttpPost]
    public void Post([FromBody]MyClass myClass)
    {
        _myService.Add(myClass);
        // Load your rules from somewhere 
        _rulesHubContext.Clients.All.InvokeAsync("SendRules", rules);
    }
}

1
嗨,感谢您的评论。您分享的问题似乎是针对另一个SignalR版本的,我无法使用Microsoft.AspNetCore.SignalR.Infrastructure。我尝试了您分享的代码,但它对我不起作用。客户端没有获取规则。我不明白现在应该在RulesHub上实现什么,因为您建议的更改将不再使用类所拥有的唯一方法。 - joacoleza
@jaocoleza 你试过我的解决方案了吗?你可以让你的中心保持空白。连接需要中心。你可以向中心添加客户端可以在服务器上执行的方法。 - Stephu
此外,我还需要将 _private RulesHub rulesHub; 更改为 _private IHubContext<RulesHub> _rulesHubContext;_,并将 rulesHubContext.All.InvokeAsync("SendRules", rules); 更改为 __rulesHubContext.Clients.All.InvokeAsync("SendRules", rules);_。 - joacoleza
@joacoleza:你可以在你的hub上重写OnConnectedAsync方法,在那里你可以添加一个断点。然后你就可以看到客户端是否连接到了hub:public override Task OnConnectedAsync() { ... } - Stephu
@joacoleza 抱歉我的错误。我写得太快了。它还没有被更正。 - Stephu
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接