SignalR IHubContext和线程安全

Oli*_*old 2 c# signalr signalr-hub

在下面的代码示例中,我实现了一个应该实现以下功能的SignalR Hub:

  • 客户端可以通过调用Hub的Subscribe方法来监听Foo实例的更改,其中包含一堆被视为组名的ID
  • 取消订阅通过调用Unsubscribe来模拟
  • Web应用程序的服务层可以通过调用OnFooChanged来通知已经发生更改的相应ID(组)的连接客户端

使用单例作为集线器上下文是安全的还是我每次都需要在OnFooChanged中获取它?关于其他方法的实施的反馈也是受欢迎的.毕竟我是SignalR的新手.

[Export]
public class FooHub : Hub
{
  private static readonly Lazy<IHubContext> ctx = new Lazy<IHubContext>(
    () => GlobalHost.ConnectionManager.GetHubContext<FooHub>());

  #region Client Methods 

  public void Subscribe(int[] fooIds)
  {
    foreach(var fooId in fooIds)
      this.Groups.Add(this.Context.ConnectionId, fooId.ToString(CultureInfo.InvariantCulture));
  }

  public void Unsubscribe(int[] fooIds)
  {
    foreach (var fooId in fooIds)
      this.Groups.Remove(this.Context.ConnectionId, fooId.ToString(CultureInfo.InvariantCulture));
  }

  #endregion // Client Methods

  #region Server Methods

  /// <summary>
  /// Called from service layer when an instance of foo has changed
  /// </summary>
  public static void OnFooChanged(int id)
  {
    ctx.Value.Clients.Group(id.ToString(CultureInfo.InvariantCulture)).onFooChanged();
  }

  #endregion // Server Methods
}
Run Code Online (Sandbox Code Playgroud)

Lar*_*ner 5

服务器广播教程引用:

您只想获取上下文一次有两个原因:获取上下文是一项昂贵的操作,并且获取它一次可确保保留发送到客户端的预期消息顺序.

所以,换句话说:使用Lazy单例是安全的,也是推荐的方法.如果您每次要发送给客户端时都会获得新的上下文,那么您将面临以不同于预期的顺序发送邮件的风险.

我不知道为什么你可能想要定期获得新的背景.