服务工作者的生命周期有限,您不应该使用网络套接字或服务器发送事件之类的东西。
推送通知以不同的方式实现。
在您的页面中,您需要订阅用户推送通知。订阅是一个端点 URL(以及一组密钥,如果您计划使用有效负载)。用户订阅后,您需要将订阅信息发送到您的服务器。
服务器将通过对端点 URL 的 POST 请求向用户发送推送通知。
当推送通知到达时,Service Worker 将被唤醒,其“推送”事件处理程序将被执行。
一个简单的示例(对于更复杂的示例,请查看ServiceWorker 食谱 https://serviceworke.rs/).
Page
// Register a Service Worker.
navigator.serviceWorker.register('service-worker.js')
.then(function(registration) {
// Use the PushManager to get the user's subscription to the push service.
return registration.pushManager.getSubscription()
.then(function(subscription) {
// If a subscription was found, return it.
if (subscription) {
return subscription;
}
// Otherwise, subscribe the user (userVisibleOnly allows to
// specify that you don't plan to send notifications that
// don't have a visible effect for the user).
return registration.pushManager.subscribe({
userVisibleOnly: true
});
});
}).then(function(subscription) {
// subscription.endpoint is the endpoint URL that you want to
// send to the server (e.g. via the Fetch API or via
// XMLHTTPRequest).
console.log(subscription.endpoint);
// Here's an example with the Fetch API:
fetch('./register', {
method: 'post',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
endpoint: subscription.endpoint,
}),
});
});
服务人员
// Register event listener for the 'push' event.
self.addEventListener('push', function(event) {
// Keep the service worker alive until the notification is created.
event.waitUntil(
self.registration.showNotification('Title', {
body: 'Body',
})
);
});
Server
在服务器中,只需向端点 URL 发送 POST 请求即可。
例如,使用卷曲:
curl -X POST [endpointURL]
或者,如果您使用 Node.js,则可以使用 web-push 库(https://github.com/marco-c/web-push https://github.com/marco-c/web-push):
var webPush = require('web-push');
webPush.sendNotification(req.query.endpoint, req.query.ttl);
在 Java 中,您可以使用此类(https://github.com/marco-c/java-web-push https://github.com/marco-c/java-web-push)隐藏了实现的细节以及当前版本的 Firefox 和 Chrome 中协议之间的差异(由于 Chrome 即将使用 Web Push 协议,这些差异注定会消失)。
下面是一个“手动”示例,其中包含实现 Web Push 协议的推送服务(当前仅适用于 Firefox):
URL url = new URL(endpointURL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write("");
writer.flush();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
writer.close();
reader.close();