gpt4 book ai didi

signalr - SignalR 组可以在不同的集线器之间共享吗?

转载 作者:行者123 更新时间:2023-12-04 20:08:41 28 4
gpt4 key购买 nike

找到后this update围绕与组的通信,似乎一个组与集线器名称无关。如果这是正确的(如果我弄错了,请告诉我)集线器有什么方法可以访问另一个集线器的组,或者更好地拥有某种全局组?
我的问题是我有一个将客户端添加到组的集线器:

public class GameService : Hub, IGameService
...
public void CreateNewGame(CreateGameDto game)
{
game.Creator = UserRepo.GetUser(Context.ConnectionId);
var newGame = GameRepo.CreateNewGame(game);
Groups.Add(Context.ConnectionId, newGame.GameId.ToString(CultureInfo.InvariantCulture));
Clients.Caller.JoinedGame(newGame);
}
另一个集线器完全需要向该组广播:
    public class MessagingService : Hub , IMessageService
...
public void AddMessage(MessageDto message)
{
message.User = UserRepo.GetUser(Context.ConnectionId);
MessageRepo.AddMessage(message);
Clients.Group(message.User.GameId.ToString(CultureInfo.InvariantCulture))
.ReceivedMessage(message);
}
截至目前,客户端从未收到此广播。
编辑添加客户端代码。
这是客户端信号器设置,我创建了一个框架,允许我将服务接口(interface)与 CaSTLe Dynamic Proxy 一起使用,这样我就不会通过字符串名称调用服务和方法。
public abstract class BaseClientProxy<TServer,TClient>
{
public TServer ServiceProxy;

protected BaseClientProxy(HubConnection conn)
{
ServiceProxy = CreateProxy(conn);
}

private ProxyGenerator _generator;
protected IHubProxy Proxy;
protected TClient Receiver;

protected TServer CreateProxy(HubConnection conn)
{
Proxy = conn.CreateHubProxy<TServer>();

_generator = new ProxyGenerator();

return (TServer)_generator.CreateInterfaceProxyWithoutTarget(typeof(TServer), new HubProxyInterceptor(Proxy));
}

public void SetReceiver(TClient receiver)
{
Receiver = (TClient)_generator.CreateInterfaceProxyWithTarget(typeof(TClient), receiver);
RegisterEvents();
}

protected void RegisterEvents()
{
Action<MethodInfo> regAction = RegisterEvent<object>;
var methods =
typeof (TClient).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
foreach (var methodInfo in methods)
{
var locInfo = methodInfo;
if (locInfo.GetParameters().Length > 0)
{
var regMethod = typeof(BaseClientProxy<TServer, TClient>).GetMethodExt(regAction.Method.Name, typeof(MethodInfo));
var genAction = regMethod.MakeGenericMethod(locInfo.GetParameters()[0].ParameterType);
genAction.Invoke(null, new object[] { locInfo });
}
else
{
Proxy.On(locInfo.Name, () =>locInfo.Invoke(Receiver, null));
}
}
}

protected void RegisterEvent<TDto>(MethodInfo method)
{
Proxy.On<TDto>(method.Name, x => method.Invoke(Receiver, new object[] {x}));
}
}

public class HubProxyInterceptor : IInterceptor
{
protected IHubProxy Proxy;

public HubProxyInterceptor(IHubProxy proxy)
{
Proxy = proxy;
}

protected async void Invoke<TDto>(string methodName, TDto dto)
{
await Proxy.Invoke(methodName, dto);
}

protected async void Invoke(string methodName)
{
await Proxy.Invoke(methodName);
}

public void Intercept(IInvocation invocation)
{
if (invocation.Arguments.Length > 0)
{
Invoke(invocation.Method.Name, invocation.Arguments[0]);
}
else
{
Invoke(invocation.Method.Name);
}
}
}
这些片段来自一个单例类,该类在 Windsor 容器中建立连接并注册服务。
private SignalRManager()
{
var settings = Settings.GetSettings<IClientSettings>(ConfigurationManager.AppSettings);

Connection = new HubConnection(settings.SignalRServerUri);

ioc = new WindsorContainer();
ioc.Register(
Component.For<BaseClientProxy<IUserService, IUserClient>>().Instance(new UserServiceProxy(Connection)),
Component.For<BaseClientProxy<IDrawingService, IDrawingClient>>().Instance(new DrawingServiceProxy(Connection)),
Component.For<BaseClientProxy<IMessageService, IMessageClient>>().Instance(new MessageServiceProxy(Connection)),
Component.For<BaseClientProxy<IScoreBoardService, IScoreBoardClient>>().Instance(new ScoreBoardServiceProxy(Connection)),
Component.For< BaseClientProxy<IGameService,IGameClient>>().Instance(new GameServiceProxy(Connection)));
Connection.Start().Wait();
}
public TClient GetService<TClient,TReceiver>(TReceiver receiver) where TClient : IService
{
var proxy = ioc.Resolve<BaseClientProxy<TClient, TReceiver>>();
proxy.SetReceiver(receiver);
return proxy.ServiceProxy;
}
在此代码中,HubProxyInterceptor 负责对服务器进行所有调用。
BaseClientProxy 中的 RegisterEvents 方法负责将调用从服务器连接到客户端。 TServer 和 TClient 类型参数是 2 个不同但相似的接口(interface),TServer 将由服务器端的 Hub 类实现,TClient 由我的 WPF View 模型实现,这是在调用 SetReceiver 时传入的。

最佳答案

您可以使用GetHubContext在 MessagingService.AddMessage 中将消息发送到另一个 Hub 的组。

public void AddMessage(MessageDto message)
{
IHubContext gameContext = GlobalHost.ConnectionManager.GetHubContext<GameService>();

message.User = UserRepo.GetUser(Context.ConnectionId);
MessageRepo.AddMessage(message);

gameContext.Clients.Group(message.User.GameId.ToString(CultureInfo.InvariantCulture))
.ReceivedMessage(message);
}

您可以存储 gameContext如果您不想在每次调用 AddMessage 时重新创建它,请在字段中。

关于signalr - SignalR 组可以在不同的集线器之间共享吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21742295/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com