服务工作者请求,服务器连续响应?

时间:2016-01-27 07:05:09

标签: javascript servlets push-notification server-sent-events service-worker

我正在使用服务器发送事件来显示通知。我创建了一个服务工作者,并且在运行项目后,我使用EventSource连接服务器(在我的情况下,我使用了servlet。)。一切都很好。

但是事件内部的内容很有效。我想知道为什么? 我的另一个问题是

关闭标签后。它停止发送通知。服务工作者正在运行,服务器也在运行。但为什么它会停止?

这是我的服务工作者代码。

var eventSource = new EventSource("HelloServ");
//MyDiv1 is a custom event
eventSource.addEventListener("MyDiv1",function(event){
    console.log("data from down" , event.data);

    var title = event.data;
    //below notification is displaying continuously. why ?
var notification = new Notification(title, {
icon: 'http://cdn.sstatic.net/stackexchange/img/logos/so/so-icon.png',
body: event.data,
});
notification.onclick = function () {
window.open("http://ageofthecustomer.com/wp-content/uploads/2014/03/success.jpg");      
        };
    console.log("down");
}); 

这是我的servlet代码;

response.setContentType("text/event-stream");   
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = response.getWriter();
        String upVote = "my up vote";
            writer.write("id:1\n");
            writer.write("event:myid\n");
            writer.write("data: "+ upVote +"\n");
            writer.write("data: "+"new data 2\n\n");
            System.out.println("servlet "+ i);
            writer.flush();
            i++;
writer.close();

1 个答案:

答案 0 :(得分:4)

服务人员的生命周期有限,您不应该使用Web套接字或服务器发送事件等内容。 推送通知以不同的方式实现。

在您的页面中,您需要为用户订阅推送通知。订阅是端点URL(如果您计划使用有效负载,则为一组密钥)。订阅用户后,您需要将订阅信息发送到您的服务器。

服务器将通过对端点URL的POST请求向用户发送推送通知。

当推送通知到达时,服务工作人员将被唤醒,其推送'事件处理程序将被执行。

一个简单的例子(对于更复杂的例子,请看一下ServiceWorker Cookbook)。

网页

// 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',
    })
  );
});

服务器

在服务器中,只需向端点URL发送POST请求即可。 例如,使用curl:

curl -X POST [endpointURL]

或者,如果您正在使用Node.js,则可以使用网络推送库(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)隐藏实现的详细信息以及当前版本的Firefox和Chrome中的协议之间的差异(由于Chrome将要使用,这些差异将会消失Web推送协议很快)。 这是"手册"使用推送服务实现Web推送协议的示例(目前仅适用于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();