SignalR项目外的呼叫客户端方法

时间:2017-02-01 12:06:01

标签: c# .net winforms signalr signalr.client

我担心如何在以下场景中使用SgnalR:

有一个非中心服务项目定期运行耗时的任务。 应通知客户端正在运行的任务的进度。经过一些研究,SignalR似乎是出于这个目的的正确选择。

问题是,我希望Service-Hub-Clients系统尽可能松散耦合。因此,我在IIS中托管了Hub,并且正如SignalR文档建议的那样,在外部项目中添加了对Hub上下文的引用并调用了客户端方法:

    hubContext = GlobalHost.ConnectionManager.GetHubContext<TheHub>()
    hubContext.Clients.All.progress(n, i);

客户方:

    private void InitHub()
    {
        hubConnection = new HubConnection(ConfigurationManager.AppSettings["hubConnection"]);

        hubProxy = hubConnection.CreateHubProxy("TheHub");
        hubConnection.Start().Wait();
    }

    hubProxy.On<int, int>("progress", (total, done) =>
        {
            task1Bar.Invoke(t => t.Maximum = total);
            task1Bar.Invoke(t => t.Value = done);
        });

在客户端,该方法没有被调用,经过两天的研究后我无法正常工作,尽管从Hub本身打电话时,它运行正常。我怀疑我错过了一些配置

1 个答案:

答案 0 :(得分:2)

如果调用者将是除Web项目之外的任何项目,则无法在Hub类或服务中使用GlobalHost.Connection管理器。

GlobalHost.ConnectionManager.GetHubContext<TheHub>()

您应该创建一个服务类,它将从调用者中抽象出集线器。服务类应具有以下内容:

// This method is what the caller sees, and abstracts the communication with the Hub
public void NotifyGroup(string groupName, string message)
{
  Execute("NotifyGroup", groupName, message);
}

// This is the method that calls the Hub
private void Execute(string methodName, params object[] parameters)
{
  using (var connection = new HubConnection("http://localhost/"))
  {
    _myHub = connection.CreateHubProxy("TheHub");
    connection.Start().Wait();
    _myHub.Invoke(methodName, parameters);
    connection.Stop();
  }
}

最后一点是集线器本身,应该是这样的:

public void NotifyGroup(string groupName, string message)
{
  var group = Clients.Group(groupName);
  if (group == null)
  {
    Log.IfWarn(() => $"Group '{groupName}' is not registered");
    return;
  }
  group.NotifyGroup(message);
}