AngularJS Comet("实时")app双向模块间通信

时间:2014-10-05 13:01:34

标签: angularjs real-time comet circular-dependency bidirectional

我有一个大型复杂的AngularJS Comet application(“实时”)。客户端将数据发送到服务器,并从服务器接收有关其他用户已启动的事件的通知。

以最简单的形式,应用程序有这些客户端组件(下面的“服务”可能是AngularJS .service或.factory,无论如何)

  • [Object] Controller:可以是任何对象,例如StudentTeacherLessonDocument
  • [Object] Service:拥有对象的模型,并具有对该数据进行操作的方法
  • Socket Service:套接字库的包装器

通话可以双向进行

  • 用户更新内容> [Object] Controller> [Object] Service> Socket Service>服务器
  • 服务器> Socket Service> [Object] Service> [Object] Controller>用户通知

在这种情况下,双向模块间通信的最佳架构是什么?

这就是我认为的选择。如果我把它们遗弃,请建议其他好的。

  1. 使用circular dependency fudge。我读到的任何地方似乎都不应该这样做,包括Lu4在他的“软糖”答案中。另一方面,这样做意味着您可以在两个方向上进行方法调用,从而在整个应用程序中保持模块间通信的一致性。
  2. 在一个方向上使用依赖项注入和方法调用,在另一个方向上使用事件。过度使用事件有some opposition。这是一个过度使用的情况吗?
  3. 在两个方向上使用事件。更接近“过度使用”,但在整个应用程序中保持模块间通信一致。
  4. 使用Mediator pattern,即具有两个方向协调的中央协调服务。我不确定这与使用事件有什么不同或更好,其中$ rootScope成为所有事件及其回调被注册的“调解者”。
  5. 模块之间的某种长轮询,例如,[Object] Controller调用[Object] Service,它返回一个promise,然后调用Socket Service,它也返回一个promise ,当Socket Service收到一些数据时,承诺会解析链,此时[Object] Controller会发起另一个请求。

1 个答案:

答案 0 :(得分:1)

一个干净的解决方案是将经典DI用于用户发起的方向。由于您的[Object] Service包含模型,您只需更新它(如果您的实现是干净的,即您在任何地方都使用注入的模型对象)。

因此,问题在于如何从Socket服务到[Object]服务获取新的更新。由于您的套接字服务实际上不应该知道您的模型详细信息注入模型不是一个合理的解决方案(单独留下如此创建的循环依赖)。从服务器获取客户端应用程序中的任何内容的更新都在一个事件的定义中(可以随时出现),因此我认为在您的SocketService中获取$RootScope并进行广播是非常合理的。在此事件中,您的[对象]服务需要根据新信息更新模型。

如果您有许多服务,并且通常服务器启动的事件仅与其中一个或极少数相关,则可能的优化是从服务器发送一个字段受此更新影响的模型。这是合理的,因为服务器已经知道模型并且它使Socket服务能够在不知道xxx意味着什么的情况下广播updateFor:xxx事件。然后,相应的[Object]服务仅侦听updateFor:[Object]事件。但是一如既往地进行优化,如果简单的方法已经适合你,就不要这样做。