多个应用程序之间的通信

Communication between multiple applications

本文关键字:通信 之间 应用程序      更新时间:2023-09-26

假设我在浏览器(窗口1)中运行了一个角度SPA。假设有一些活动导致我们在一个新窗口(由$window.open()打开)(窗口2)内启动一个单独的角度应用程序。

Windows 1&2人希望保持一定程度的联系。它们运行不同的应用程序,但都处理相同的主题。当一个改变状态时,另一个可能需要对此做出反应。反之亦然。

我正在为这两个应用程序寻找一些好方法,在两个独立的浏览器窗口中来回发送事件。

现在,为了好玩,可能还有另一个窗口(窗口3)运行与窗口1相同的应用程序。这个单独的实例不应该以任何方式受到windows 1&2.当然,窗口3可以启动它自己的窗口2(窗口4)。

所以窗口1&2(运行不同的应用程序)应该能够来回发送消息。以及窗口3&4类似。但是1不应该影响3&4等等。

它们之间的明显关系是,称为$window.open()的窗口1和窗口2可以访问$window.opener,所以它们都可以访问window对象,但我如何"分析"这种情况?

当前的实现是使用CCD_ 5并监视存储事件来链接窗口1&2,但这当然完全不能满足一旦windows 3&4个出现。

这听起来是一个使用应用程序事件的好例子。

您需要一个对象具有发布/订阅接口:

var dispatcher = {
    subscriptions: {},
    publish: function(eventName, publisher, data) {
        // loop through subscribers and notify them, passing publisher and data
        // var subscriber = this.subscribers[eventName][i];
        // subscriber.callback.call(subscriber.context, publisher, data);
    },
    subscribe: function(eventName, context, callback) {
        this.subscriptions[eventName] = this.subscriptions[eventName] || [];
        this.subscriptions[eventName].push({
            context: context,
            callback: callback
        });
    }
};

打开新窗口时,请将此对象引用设置为新窗口上的属性。

var win = window.open(...);
win.dispatcher = dispatcher;

现在,包括"顶部"窗口在内的每个窗口都应该有一个名为dispatcher的全局变量,您可以使用它来订阅和发布事件:

(从主窗口)

dispatcher.subcribe("item.added", this, function(publisher, data) {
    // "publisher" is the object publishing the event
    // "data" is arbitrary data passed along in the event
});

(从子窗口)

dispatcher.publish("item.added", this, {
    name: "Foo"
});

我还没怎么使用AngularJS,所以我不确定它是否带有DOM事件之外的某种事件框架。JavaScript中有很多pub/sub模型的实现,你可能会向谷歌搜索扔一个飞镖,然后找到一个。我创建了一个简单的JavaScript类库,可能符合要求。它没有外部依赖关系:https://github.com/gburghardt/events

优点

  • 性能非常好,因为它不依赖于HTTP请求/响应生命周期
  • 设置起来相当简单
  • 跨浏览器支持,无需破解或polyfill

缺点

  • 如果主窗口关闭,那么您的子窗口将失去与外部世界的连接,已发布的事件将被置若罔闻

如果你足够幸运,所有窗口都在同一个域上,那么你可以使用前面提到的postMessage,甚至更好的HTML5 localStorage。您在这里有一篇文章和演示。主要是发生了什么:

所有窗口监听存储事件,类似于:

window.addEventListener("storage", handle_storage, false); 

对于每个窗口,您可以有一个不同的handle_storage函数或一个通用函数来检查哪个url负责存储事件。

优点:

  • 没有引用其他窗口
  • 即使主窗口关闭也会工作
  • 标准且广泛可用的IE8+、FF3.5+、Chrome4+、
  • "本机"Javascript没有外部库。在Angular JS应用程序中轻松集成

缺点:

  • 没有(至少据我所知)

希望这会有所帮助。