支持中经常提出的一个问题是如何减少并发 Pusher 连接并避免与您的计划相关的任何限制。鉴于每当您的页面在新选项卡中加载时都会创建与我们的 API 的新连接 - 如果客户可以跨多个选项卡共享单个连接,这将对客户非常有利。解决方案?在共享工作线程中使用 Pusher ,我们可以为每个浏览器窗口仅保留一个 Websocket 连接。这样,如果您的用户在多个选项卡中打开您的应用程序,您就可以保持较低的连接数。这篇博文将为您提供有关如何设置的分步指南。如果您在任何时候遇到困难,请随时查阅我们在 Github 上的示例

最近,我们自己的 Paweł Ledwoń 在博客中介绍了我们如何编写PusherJS 的同构版本,从而向新的 Javascript 环境开放我们的 API。除了 NodeJS 和 React Native 之外,使用 PusherJS 的最棒的新方法之一是在浏览器工作线程中。

对于该领域的新手来说,Web Worker本质上是在单独的线程中运行的 Javascript 代码,独立于其他脚本并且完全与 DOM 隔离。

目前不可能在工作线程中使用官方的 PusherJS,因为该库使用 DOM 进行 JSONp 并加载 XHR 回退和 SockJS 等依赖项。然而,通过实验性的Pusher-websocket-iso,消除了对 DOM 的依赖,从而让客户可以在这个新环境中使用 Pusher。

解决方案?在共享工作线程中使用 Pusher ,我们可以为每个浏览器窗口仅保留一个 Websocket 连接。这样,如果您的用户在多个选项卡中打开您的应用程序,您就可以保持较低的连接数。这篇博文将为您提供有关如何设置的分步指南。如果您在任何时候遇到困难,请随时查阅我们在 Github 上的示例

入门

让我们制作一个小应用程序,它可以简单地连接到 Pusher 并显示任何传入的消息。我们将查看仪表板调试控制台上正在建立的新连接和发送的消息。

当您位于仪表板上时,请继续获取您的应用程序密钥。像往常一样,我们将使用它连接到 Pusher。

下载Pusher-websocket-iso 的工作程序发行版,并将其命名为类似"pusher.worker.js""index.html"为您的网页创建一个文件,并"shared_worker.js"为您的工作代码创建一个名为的文件。

网页内部

我们在此页面上将拥有的只是一个用于显示传入消息的元素,以及一个用于断开页面与 Pusher 的按钮。

标记

1<!DOCTYPE html>
2<html>
3<head>
4  <title>Pusher + Shared Workers</title>
5  <script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
6</head>
7<body>
8
9  <button id="disconnect">Disconnect</button>
10
11  <div>
12    <p>Message: <span id="message"></span></p>
13  </div>
14
15</body>
16</html>

现在创建一个脚本标签,我们将在其中初始化我们的工作脚本。我们首先要检查浏览器是否支持 SharedWorker API:

JAVASCRIPT

1if (typeof(window.SharedWorker) === 'undefined') {
2  throw("Your browser does not support SharedWorkers")
3}
4
5var worker = new SharedWorker("./shared_worker.js");

为了从我们的工作线程接收消息,我们必须绑定它的端口,并设置一个onmessage函数。在我们的例子中,我们可以将接收到的对象字符串化并将其呈现给元素#message。另外,如果工作程序发生错误,我们只需注销该消息并关闭工作程序:

JAVASCRIPT

1worker.port.onmessage = function(evt){
2  console.log(evt.data);
3  $('#message').text(JSON.stringify(evt.data));
4};
5
6worker.onerror = function(err){
7  console.log(err.message);
8  worker.port.close();
9}

然后我们可以通过打开端口来工作:

JAVASCRIPT

1worker.port.start();

Worker内部

为了导入,"pusher.worker.js"我们可以使用特定于工作人员的特殊 importScripts 函数。然后,像往常一样,使用我们的应用程序密钥实例化我们的 Pusher 对象,并订阅我们的频道,在本例中为"test_channel"

JAVASCRIPT

1importScripts("pusher.worker.js");
2
3// Connect to Pusher
4var pusher = new Pusher('1fb94680701ab31a3139', {
5  encrypted: true
6});
7
8// Subscribe to test_channel
9var pusherChannel = pusher.subscribe('test_channel');

在监听任何特定事件之前,我们首先需要跟踪连接到共享工作线程的所有浏览器选项卡。每当选项卡连接时,工作人员都会收到一个内置"connect"事件,我们可以将选项卡的端口推送到客户端数组。然后我们通过启动以下命令打开连接port

JAVASCRIPT

1// An array of the clients/tabs using this worker
2var clients 
3
4self.addEventListener("connect", function(evt){
5
6  // Add the port to the list of connected clients
7  var client = evt.ports[0];
8  clients.push(client);
9
10  // Start the worker.
11  client.start();
12});

现在我们可以跟踪工作状态下连接的选项卡,我们现在要做的就是绑定到 PusherChannel 上的 Pusher 事件并将数据传递给所有客户端。在工人的世界中,我们在网页和工人之间进行通信的方式是通过发送消息。这是通过一个简单的postMessage函数实现的:

JAVASCRIPT

1// bind to 'my_event' on pusherChannel
2pusherChannel.bind('my_event', function(data) {
3
4  // Relay the payload on to each client
5  clients.forEach(function(client){
6    client.postMessage(data);
7  });
8});

瞧,我们已经设置了网页和工作人员。访问者将访问该页面,该页面将打开与共享工作人员的连接。该工作人员会将任何传入的 Pusher 消息转发到网页,该网页将简单地对有效负载进行字符串化并将其显示在网页上。让我们看看结果如何。

魔术

在仪表板上打开 Pusher 调试控制台。在这里您将能够看到任何新的连接,并向您的频道发送消息。

在单独的窗口中打开您的index.html文件。在调试控制台中,您应该看到已创建一个连接。展开事件创建器并在 test_channel 上发送名为 my_event 的事件,并使用您希望的任何负载。您现在应该在 DOM 上看到它。

现在,打开一个新选项卡。您应该在仪表板上看到没有建立新连接。发送另一个事件,两个选项卡都应显示该消息。

任务完成!现在你有了一个小应用程序,可以让你通过跨选项卡共享来减少连接数量。

让我们知道您的身体情况如何!

如果您打算使用此技术来构建实时应用程序,请随时向我们发送推文,让我们知道。我个人对实验性同构 Javascript 库感到非常兴奋,并且非常欢迎任何新的贡献。显然它仍然是非官方的,因为它仅适用于支持 XHR 并且不需要 JSONp 的现代浏览器,但我渴望听到有关我们可以向客户端开放的新环境的建议。同样,如果您正在使用任何其他类型的 Web Workers、React Native 或 Electron 构建应用程序,我们很想知道!

用 Shared Workers减少 WebSocket 连接数
标签: