我担心如何在以下场景中使用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本身打电话时,它运行正常。我怀疑我错过了一些配置
答案 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);
}