SignalR IHubContext和线程安全

奥利弗·韦希霍尔德(Oliver Weichhold)

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

  • 客户端可以通过调用带有一组ID的Hub的Subscribe方法来监听Foo实例的更改,这些ID在内部被视为组名
  • 通过调用“取消订阅”来取消订阅模拟工作
  • 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
}
拉斯·霍普纳(LarsHöppner)

引用服务器广播教程

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

因此,换句话说:使用Lazy单例是安全的,并且推荐使用此方法。如果每次要发送给客户时都有新的上下文,则可能会以与预期不同的顺序发送消息。

我不知道您为什么要定期获取新上下文的任何原因。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章