支持中经常提出的一个问题是如何减少并发 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 构建应用程序,我们很想知道!