如安在 Service Worker 和网页客户端之间发送消息 已翻译 100%

昂贵甜头昂贵甜头 投递于 2018/12/29 17:18 (共 8 段, 翻译完成于 01-05)
浏览 3050
收藏 22
0
加载中

Service Workers 是一个为页面任务的后台处理器。供给离线web apps是Service Workers今朝最让人感兴趣的功能,同时Service Workers可以或许管理一个本地的资本缓存,当搜集连接状况是正常的时辰,这个本地资本缓存可以或许主动跟办事器停止同步。这是非常酷的,但我想谈一下Service Workers的另外一个用处,应用它来管理多个web页面之间的通信。

例如,你能够有一个应用翻开在多个浏览器页签中。Service Workers可以或许更新一个页签当其他页签有一个事宜触发,也能够做到当办事器收回一个消息后,一切页签的内容将被更新。

昂贵甜头昂贵甜头
翻译于 2019/01/02 13:51
0

一个 Service Workers 可以控制多个客户端页面,例如ServiceWorker会主动的控制它范围内的一切客户端页面,它的范围是指你站点下的url,平日来讲是Service Worker script文件的途径。

在这个demo里,我们将应用三个文件 client1.html client2.html service-worker.js

起首我们注册service worker 在 client1.html

<!doctype html>
<html>
<head>
    <title>Service Worker - Client 1</title>
</head>
<body>
    <script>
        if('serviceWorker' in navigator){
            // Register service worker
            navigator.serviceWorker.register('/service-worker.js').then(function(reg){
                console.log("SW registration succeeded. Scope is "+reg.scope);
            }).catch(function(err){
                console.error("SW registration failed with error "+err);
            });
        }
    </script>
</body>
</html>

接着我们创建一个根本的 Service worker 在service-worker.js

console.log("SW Startup!");

// Install Service Worker
self.addEventListener('install', function(event){
    console.log('installed!');
});

// Service Worker Active
self.addEventListener('activate', function(event){
    console.log('activated!');
});

我不会去解释他是怎样任务的,由于在很多处所都有记录(译者注:作者的意思是很多处所都有console.log

昂贵甜头昂贵甜头
翻译于 2019/01/02 13:53
0

我们同时创建了client2.html 我们只会在client1注册serviceworker,所以不须要有反复的代码在这里。serviceworker运转的时辰将会主动的控制它的感化域下的页面。

<!doctype html>
<html>
<head>
    <title>Service Worker - Client 2</title>
</head>
<body>
    <script>
    </script>
</body>
</html>

假设你在浏览器上拜访client1.html你应当会看到由console.log输入的注册信息。在Chrome(48+)中,你可以在开辟对象的“Resouces”选项卡下点击“inspect”,为办事任务者翻开一个检查器。(译者注:这个我没有找到)。当你翻开client2.html在新的浏览器页签,你可以在开辟对象内的“Controlled Clients”找到它

如今我们可以持续讲风趣的器械了。

昂贵甜头昂贵甜头
翻译于 2019/01/02 13:53
0

起首我们让客户端发消息给serviceworker。一切我们须要去加一个消息的处理在service-worker.js

self.addEventListener('message', function(event){
    console.log("SW Received Message: " + event.data);
});

如今我们增长一个发消息的函数在两个客户端里

function send_message_to_sw(msg){
    navigator.serviceWorker.controller.postMessage("Client 1 says '"+msg+"'");
}

假设你在客户端页面的控制台内调用send_message_to_sw("Hello"),你因该可以在serviceworker的控制台内看到有消息显示

昂贵甜头昂贵甜头
翻译于 2019/01/02 13:54
0

我们可以进一步的让serviceworker去照应客户端发来的消息。完成它我们须要去改进我们的send_message_to_sw函数。我们应用‘Message Channel’,Message Channel可以或许供给了一对端口(port)来停止通信。我们将一个援用连同消息一路发送到端口的另外一端,所以Service Worker可以或许应用它去停止答复。我们也能够对这些照应消息做一些处理。为了便利起见,我们还应用Promise来处理等待照应。

译者注:这里说的端口(port)用于页面与serviceworker之间的通信

function send_message_to_sw(msg){
    return new Promise(function(resolve, reject){
        // Create a Message Channel
        var msg_chan = new MessageChannel();

        // Handler for recieving message reply from service worker
        msg_chan.port1.onmessage = function(event){
            if(event.data.error){
                reject(event.data.error);
            }else{
                resolve(event.data);
            }
        };

        // Send message to service worker along with port for reply
        navigator.serviceWorker.controller.postMessage("Client 1 says '"+msg+"'", [msg_chan.port2]);
    });
}

service-worker.js我们修改了监听器,与消息一路发送照应在端口

self.addEventListener('message', function(event){
    console.log("SW Received Message: " + event.data);
    event.ports[0].postMessage("SW Says 'Hello back!'");
});

 

昂贵甜头昂贵甜头
翻译于 2019/01/02 13:55
0

如今假设在你的客户端控制台履行send_message_to_sw("Hello").then(m => console.log(m)),你将看到信息显示在serviceworker的控制台里,在客户真个控制台将会有答复。请留意,我们应用Promise then函数来等待照应和箭头函数,由于如许更轻易去测定(译者注:这里type我翻译成控制)。

如今我们有了一个让客户端发消息给serviceworker同时serviceworker可以或许答复的机制。您可以应用它让客户机检查长时间运转的流程的状况,让serviceworker将消息转发给一切客户端或其他一些很酷的器械。

奇异的任务来了!

昂贵甜头昂贵甜头
翻译于 2019/01/02 13:55
0

如今我们许可serviceworker广播一个事宜到一切的客户端让一切客户照应。这与之前应用的机制类似,只是角色颠倒了。

起首我们在客户端增长一个消息监听器,我们增长了测试serviceworker兼容性的代码,其他的处所简直雷同。

if('serviceWorker' in navigator){
    // Handler for messages coming from the service worker
    navigator.serviceWorker.addEventListener('message', function(event){
        console.log("Client 1 Received Message: " + event.data);
        event.ports[0].postMessage("Client 1 Says 'Hello back!'");
    });
}

接着我们给serviceworker增长一个发送消息给客户真个函数。这也跟之前很类似,只是我们须要供给给一个客户端对象(一个页面的应用),这个对象能告诉我们要往哪里发消息。

function send_message_to_client(client, msg){
    return new Promise(function(resolve, reject){
        var msg_chan = new MessageChannel();

        msg_chan.port1.onmessage = function(event){
            if(event.data.error){
                reject(event.data.error);
            }else{
                resolve(event.data);
            }
        };

        client.postMessage("SW Says: '"+msg+"'", [msg_chan.port2]);
    });
}

 

昂贵甜头昂贵甜头
翻译于 2019/01/02 13:56
0

serviceworker API供给了获得一切已连接客户端援用的接口。我们可以将其封装在一个便利的函数中,以便向一切客户机广播消息(留意,我们再次应用箭头函数)。

function send_message_to_all_clients(msg){
    clients.matchAll().then(clients => {
        clients.forEach(client => {
            send_message_to_client(client, msg).then(m => console.log("SW Received Message: "+m));
        })
    })
}

如今假设我们在serviceworker的控制台内履行send_message_to_all_clients('Hello'),您将看到在一切客户端控制台中接收到的消息,和在serviceworker控制台中客户机的照应。

 

昂贵甜头昂贵甜头
翻译于 2019/01/02 13:57
0
本文中的一切译文仅用于进修和交换目标,转载请务必注明文章译者、出处、和本文链接。
我们的翻译任务遵守 CC 协定,假设我们的任务有侵犯到您的权益,请及时接洽我们。
加载中

评论(3)

一小我的中台
一小我的中台
关于拦截要求和其它的器械也不提
一小我的中台
一小我的中台
讲的嘎但是止, 也没有解释白为甚么要用:MessageChannel
bosscheng
bosscheng
那种营业场景会用到呢?
前往顶部
顶部