c# - 如何使 SignalR 向具有不同主机的所有客户端发送通知
问题描述
我有一个包含 Web 应用程序和 API 应用程序的系统。两个应用程序都使用相同的服务层。(这是 3 层架构)。我在服务层组织 SignalR 并将其注册在 Web App 的 Startup.cs 文件中。
当我调用 SendToHub() 方法时,SignalR 在 Web 应用程序上工作正常。但如果我通过 API 调用 SendToHub(),则什么也没有发生。
我的期望是当 SignalR 从 API 应用程序提出时,WebApp 的前端应该得到通知。
从服务调用
public void SendSignal() {
hub_communication.SendToHub(clientId:"", incommingText:"")
}
从 Web 应用程序和 API 调用:
Service.SendSignal();
一些 SignalR 配置:
public class MainHub : Hub {
public void Register(string group)
{
var clients = GlobalHost.ConnectionManager.GetHubContext<MainHub>();
UnRegisterAll(group, null);
SignalRConnectionToGroupsMap.TryAddGroup(Context.ConnectionId, group);
Clients.Caller.groupAdded(group);
}
public void UnRegisterAll(string userID, string organizationID)
{
var rets = new List<string>();
SignalRConnectionToGroupsMap.TryRemoveAll(Context.ConnectionId, out rets);
var clients = GlobalHost.ConnectionManager.GetHubContext<MainHub>();
Clients.Caller.groupRemovedAll(userID);
}
}
public static class hub_communication
{
public static void SendToHub(string clientid, string incoming)
{
var clients = GlobalHost.ConnectionManager.GetHubContext<MainHub>();
clients.Clients.Group(clientid).receiveMessage(incoming);
}
}
public static class SignalRConnectionToGroupsMap
{
private static readonly ConcurrentDictionary<string, List<string>> Map = new ConcurrentDictionary<string, List<string>>();
public static bool TryAddGroup(string connectionId, string groupName)
{
if (!Map.TryGetValue(connectionId, out var groups))
{
return Map.TryAdd(connectionId, new List<string>() { groupName });
}
if (!groups.Contains(groupName))
{
groups.Add(groupName);
}
return true;
}
public static bool TryRemoveAll(string connectionId, out List<string> result)
{
return Map.TryRemove(connectionId, out result);
}
}
启动.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
...
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration();
map.RunSignalR(hubConfiguration);
});
}
}
解决方案
这里的问题是您的应用程序在不同的域上运行。在 Startup.cs 文件中。如下配置 SignalR:
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
推荐阅读
- apache-spark - 无法启动管理器:GridManagerAdapter,由类 IgniteSpiException 导致无法使用给定的类加载器 sun.misc.Launcher 反序列化对象
- html - 将鼠标悬停在其旁边的字符上时,CSS 使 div 看起来长大
- github - 使用 Renovate 更新特定依赖项
- r - 我可以在 rcpp 来源的 C++ 函数中使用 fprintf 吗?
- qemu - qemu-system-aarch64:-accel hvf:加速器 hvf 无效
- java - Android Studio Emulator 无法启动:VT-X 虽然已启用但无法正常工作
- c# - 发生错误时,让 Azure Insights 记录入口方法(如果不是所有方法)的请求有效负载的方法?
- r - 如何提取函数内设置的默认值?
- java - 如何在 Groovy 中检索错误消息/输出
- node.js - 如何在 cpanel 托管中托管 pern 应用程序?