2016-04-09 68 views
0

不知道我在做什么我的服务工作者实施错误。Web推送服务偶尔错误

理想情况下,我面临的问题是“网站已在此背景下刷新”。

我之前没有遇到过这个问题,但是一旦推送通知订阅人数达到600左右,就开始导致每个人都遇到问题。

var init = { method: 'GET', 
 
      headers: { 
 
       "Content-Type" : "application/javascript" 
 
      }, 
 
       mode: 'cors', 
 
       cache: 'no-cache' 
 
      }; 
 
var worker = self; 
 
var the_endpoint = ''; 
 

 
fetch(the_endpoint, init).then(function(response) { 
 
    return response.json(); 
 
}).then(function(data){ 
 
    worker.addEventListener('push', function(event) { 
 
    event.waitUntil(
 
     worker.registration.showNotification(data.title, { 
 
      body    : data.body, 
 
      icon    : data.icon, 
 
      requireInteraction : true 
 
     }) 
 
    ); 
 
    }); 
 

 
    if(data.link != '') { 
 
    worker.addEventListener('notificationclick', function(event) { 
 
     event.notification.close(); 
 
     var url = data.link; 
 
     event.waitUntil(
 
      clients.matchAll({ 
 
      type: 'window' 
 
      }) 
 
       .then(function(windowClients) { 
 
       for (var i = 0; i < windowClients.length; i++) { 
 
        var client = windowClients[i]; 
 
        if (client.url === url && 'focus' in client) { 
 
        return client.focus(); 
 
        } 
 
       } 
 
       if (clients.openWindow) { 
 
        return clients.openWindow(url); 
 
       } 
 
       }) 
 
    ); 
 
    }); 
 
    } 
 
});

尝试2不具备后台刷新的问题,但并不总是工作。

var init = { method: 'GET', 
 
      headers: { 
 
       "Content-Type" : "application/javascript" 
 
      }, 
 
       mode: 'cors', 
 
       cache: 'no-cache' 
 
      }; 
 
var worker = self; 
 
var the_endpoint = ''; 
 

 
self.addEventListener('push', function(event) { 
 
    event.waitUntil(
 
     fetch(the_endpoint, init).then(function (response) { 
 
     return response.json().then(function (data) { 
 

 
      var response = self.registration.showNotification(data.title, { 
 
      body: data.body, 
 
      icon: data.icon, 
 
      requireInteraction: true 
 
      }); 
 

 
      if (data.link != '') { 
 
      worker.addEventListener('notificationclick', function (event) { 
 
       event.notification.close(); 
 
       var url = data.link; 
 
       event.waitUntil(
 
        clients.matchAll({ 
 
        type: 'window' 
 
        }).then(function (windowClients) { 
 
        for (var i = 0; i < windowClients.length; i++) { 
 
         var client = windowClients[i]; 
 
         if (client.url === url && 'focus' in client) { 
 
         return client.focus(); 
 
         } 
 
        } 
 
        if (clients.openWindow) { 
 
         return clients.openWindow(url); 
 
        } 
 
        }) 
 
      ); 
 
      }); 
 
      } 
 

 
      return response; 
 
     }); 
 
     }) 
 
); 
 
});

回答

0

这种经常发生的原因是承诺返回event.waitUntil()没有与被显示的通知解决。

可能会显示默认的“网站已在后台刷新”的例子通知:

function handlePush() { 
    // BAD: The fetch's promise isn't returned 
    fetch('/some/api') 
    .then(function(response) { 
    return response.json(); 
    }) 
    .then(function(data) { 
    // BAD: the showNotification promise isn't returned 
    showNotification(data.title, {body: data.body}); 
    }); 
} 

self.addEventListener(function(event) { 
    event.waitUntil(handlePush()); 
}); 

相反,你可能应该写为:

function handlePush() { 
    // GOOD 
    return fetch('/some/api') 
    .then(function(response) { 
    return response.json(); 
    }) 
    .then(function(data) { 
    // GOOD 
    return showNotification(data.title, {body: data.body}); 
    }); 
} 

self.addEventListener(function(event) { 
    const myNotificationPromise = handlePush(); 
    event.waitUntil(myNotificationPromise); 
}); 

的原因,这是所有重要的是,浏览器等待传递给event.waitUntil的承诺来解决/完成,以便他们知道服务工作人员需要保持活动并运行。

当承诺解决了推送事件时,chrome将检查通知是否已显示,并且它会落入竞争条件/特定情况,以确定Chrome是否显示此通知。最好的办法是确保你有一个正确的承诺链。

我在这篇文章上写了一些关于承诺的额外注释(参见:'支付任务:承诺'https://gauntface.com/blog/2016/05/01/push-debugging-analytics