成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

web-push實(shí)現(xiàn)原理及細(xì)節(jié)介紹

hufeng / 2481人閱讀

摘要:一使用動(dòng)機(jī)與原理簡(jiǎn)述相較于移動(dòng)端本地應(yīng)用,站點(diǎn)常常缺少一項(xiàng)常用的功能推送通知。發(fā)送數(shù)據(jù)時(shí),數(shù)據(jù)必須編碼出于安全性考慮。二實(shí)現(xiàn)細(xì)節(jié)按照上一部分所說(shuō),首先進(jìn)行用戶訂閱。

一、web push 使用動(dòng)機(jī)與原理簡(jiǎn)述

相較于移動(dòng)端本地應(yīng)用,web站點(diǎn)常常缺少一項(xiàng)常用的功能:推送通知。此處的推送通知一般指由瀏覽器實(shí)現(xiàn)的消息推送,換個(gè)說(shuō)法,就是用戶在打開(kāi)瀏覽器時(shí),不需要進(jìn)入特定的網(wǎng)站,就能收到該網(wǎng)站推送而來(lái)的消息,例如:新評(píng)論,新動(dòng)態(tài)等等。

那么web push究竟是怎樣的一個(gè)流程呢,簡(jiǎn)單地說(shuō),可以分為三個(gè)步驟:

客戶端完成請(qǐng)求訂閱一個(gè)用戶的邏輯

服務(wù)端調(diào)用遵從web push協(xié)議的接口,傳送消息推送(push message)到推送服務(wù)器(該服務(wù)器由瀏覽器決定,開(kāi)發(fā)者所能做的只有控制發(fā)送的數(shù)據(jù))

推送服務(wù)器將該消息推送至對(duì)應(yīng)的瀏覽器,用戶收到該推送

第一步,客戶端請(qǐng)求訂閱用戶,過(guò)程如下:

說(shuō)明一下這三步,在第一步之前,應(yīng)用服務(wù)器需要生成應(yīng)用服務(wù)器密鑰(application server keys),其作用是標(biāo)識(shí)該服務(wù)器,保證每次發(fā)消息推送的都是同一個(gè)服務(wù)器。然后,客戶端將會(huì)請(qǐng)求用戶授權(quán)消息推送,一旦用戶授權(quán),瀏覽器就會(huì)生成一個(gè)PushScription,然后這個(gè)PushScription將會(huì)被發(fā)送至服務(wù)器,存入數(shù)據(jù)庫(kù),在后面的消息推送中使用。

第二步,應(yīng)用服務(wù)器發(fā)送web push協(xié)議標(biāo)準(zhǔn)的api,觸發(fā)推送服務(wù)器的消息推送,其中headers必須配置正確,且傳送的數(shù)據(jù)必須是比特流。

應(yīng)用服務(wù)器發(fā)送消息推送請(qǐng)求(目的是為了將更新推送到用戶的瀏覽器),為了向推送服務(wù)器發(fā)出請(qǐng)求,需要查看先前獲得的PushScription,取出其中的endpoint,即為推送服務(wù)器配置給該用戶的訪問(wèn)點(diǎn)。

一個(gè)PushScription對(duì)象如下:

{
  "endpoint": "https://random-push-service.com/some-kind-of-unique-id-1234/v2/",
  "keys": {
    "p256dh" :
"BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM=",
    "auth"   : "tBHItJI5svbpez7KI4CCXg=="
  }
}

其中的endpoint包含了推送服務(wù)器域名,path后面的部分為推送服務(wù)器為每個(gè)用戶分配的一個(gè)標(biāo)識(shí)符。

發(fā)送數(shù)據(jù)時(shí),數(shù)據(jù)必須編碼(出于安全性考慮)。推送服務(wù)器在接收到這樣一個(gè)請(qǐng)求之后,立即開(kāi)始監(jiān)聽(tīng)用戶瀏覽器是否處于在線狀態(tài),若是,則將消息推送發(fā)送至瀏覽器。

第三步,瀏覽器端接收消息推送,觸發(fā)push事件并展示

瀏覽器在接收到推送服務(wù)器發(fā)來(lái)的推送后,將其解碼并觸發(fā)一個(gè)push事件。Service Worker由于它可以在瀏覽器頁(yè)面未打開(kāi),瀏覽器未打開(kāi)時(shí)執(zhí)行,因此一般選擇它完成web push的最后一步,即響應(yīng)push事件完成展示通知等業(yè)務(wù)邏輯。

二、web push實(shí)現(xiàn)細(xì)節(jié)

按照上一部分所說(shuō),首先進(jìn)行用戶訂閱。

首先注冊(cè)一個(gè)Service Worker,若注冊(cè)成功,返回的Promise為resolve狀態(tài),如下:

function registerServiceWorker() {
  return navigator.serviceWorker.register("service-worker.js")
  .then(function(registration) {
    console.log("Service worker successfully registered.");
    return registration;
  })
  .catch(function(err) {
    console.error("Unable to register service worker.", err);
  });
}

隨后測(cè)試window環(huán)境下是否有Notification對(duì)象(此處以chrome為例,若使用firefox,uc等瀏覽器,需要遵循其相應(yīng)標(biāo)準(zhǔn),調(diào)用對(duì)應(yīng)對(duì)象方法或引入JS SDK包),測(cè)試成功,調(diào)用Notification.requestPermission請(qǐng)求用戶授權(quán)發(fā)送推送,若授權(quán)成功,將會(huì)返回"granted"。

接下來(lái)要做的就是使用注冊(cè)好的Service Worker對(duì)象,調(diào)用pushManager.subscribe方法,從客戶端獲得剛剛所說(shuō)的PushScription對(duì)象。

function subscribeUserToPush() {
  return navigator.serviceWorker.register("service-worker.js")
  .then(function(registration) {
    const subscribeOptions = {
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(
        "BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U"
      )
    };

    return registration.pushManager.subscribe(subscribeOptions);
  })
  .then(function(pushSubscription) {
    console.log("Received PushSubscription: ", JSON.stringify(pushSubscription));
    return pushSubscription;
  });
}

userVisibleOnly是為了保證推送對(duì)用戶可見(jiàn),application server key則如前文所說(shuō),是推送服務(wù)器用以識(shí)別應(yīng)用服務(wù)器的密鑰,這里的密鑰包含了公鑰和私鑰,傳輸?shù)氖枪€。同時(shí),PushScription的endpoint也是在這個(gè)過(guò)程中生成的,生成公鑰和私鑰可以使用web-push庫(kù)。

這里再次說(shuō)明一下推送服務(wù)器的不可選擇性,在調(diào)用subscribe生成PushScription時(shí),瀏覽器會(huì)向它指定的中轉(zhuǎn)服務(wù)器發(fā)送請(qǐng)求來(lái)生成endpoint和其余部分,這是沒(méi)法控制的。

PushScription中的auth和p256dh是用來(lái)控制帶載荷的push message的。

獲取到PushScription對(duì)象后,將其發(fā)往應(yīng)用服務(wù)器,此處簡(jiǎn)化了存儲(chǔ),使用nedb存下PushScription并返回Promise:

function saveSubscriptionToDatabase(subscription) {
  return new Promise(function(resolve, reject) {
    db.insert(subscription, function(err, newDoc) {
      if (err) {
        reject(err);
        return;
      }

      resolve(newDoc._id);
    });
  });
};

存儲(chǔ)完畢后,接下來(lái)就是開(kāi)發(fā)后臺(tái)管理邏輯,使得管理員能夠觸發(fā)向用戶推送消息的事件,應(yīng)用服務(wù)器所做的邏輯就是遍歷在數(shù)據(jù)庫(kù)中存儲(chǔ)的所有PushScription并推送消息,以下是使用web-push庫(kù)完成配置密鑰及聯(lián)系郵箱的示例:

const vapidKeys = {
  publicKey:
"BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U",
  privateKey: "UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls"
};

webpush.setVapidDetails(
  "mailto:[email protected]",
  vapidKeys.publicKey,
  vapidKeys.privateKey
);

不要忘了配置你在谷歌云服務(wù)(例如FCM)申請(qǐng)到的GCMApiKey:

webpush.setGCMAPIKey("");

配置完成后,就可以將subscription發(fā)送出去,使用web-push的sendNotification接口:

webpush.sendNotification(pushSubscription, "Your Push Payload Text");

推送服務(wù)器發(fā)送消息后,會(huì)觸發(fā)瀏覽器的push事件,為了控制service worker的邏輯,需要使用event.waitUntil方法,此方法接收一個(gè)promise參數(shù),在promise變?yōu)閞esolved狀態(tài)后,瀏覽器就會(huì)檢查通知是否已被展示,若是,則關(guān)閉service worker。

如果不處理未正常執(zhí)行的promise,部分瀏覽器如chrome會(huì)展示默認(rèn)消息框:

展示一個(gè)通知調(diào)用的為showNotification方法,傳的參數(shù)包括title等,如下:

var title = "Yay a message.";
var body = "We have received a push message.";
var icon = "/images/icon-192x192.png";
var tag = "simple-push-demo-notification-tag";

event.waitUntil(
    self.registration.showNotification(title, {
      body: body,
      icon: icon,
      tag: tag
    })
);

而展示notification時(shí),除了控制它的視圖層以外,也可以控制它的邏輯層,例如點(diǎn)擊消息通知后進(jìn)行某些操作等等,在先前調(diào)用showNotification時(shí)可以傳入一些參數(shù),例如,根據(jù)不同的action執(zhí)行不同的操作:

self.addEventListener("notificationclick", function(event) {
  if (!event.action) {
    // Was a normal notification click
    console.log("Notification Click.");
    return;
  }

  switch (event.action) {
    case "coffee-action":
      console.log("User ???"s coffee.");
      break;
    case "doughnut-action":
      console.log("User ???"s doughnuts.");
      break;
    case "gramophone-action":
      console.log("User ???"s music.");
      break;
    case "atom-action":
      console.log("User ???"s science.");
      break;
    default:
      console.log(`Unknown action clicked: "${event.action}"`);
      break;
  }
});
三、兼容性及其他問(wèn)題 與ajax輪詢、http長(zhǎng)連接、WebSocket的對(duì)比

ajax輪詢是通過(guò)客戶端不斷向服務(wù)端發(fā)送http請(qǐng)求,若有新消息就取回的模式保持?jǐn)?shù)據(jù)實(shí)時(shí)更新,但這種方式需要服務(wù)器有很快的處理速度和資源

http長(zhǎng)連接是客戶端向服務(wù)器發(fā)送請(qǐng)求后,若服務(wù)器沒(méi)有新數(shù)據(jù)要發(fā)送,就不返回response,一旦有了新數(shù)據(jù)返回了response,客戶端就立刻再發(fā)一個(gè)request,周而復(fù)始。事實(shí)上這是把http協(xié)議的不對(duì)稱性從客戶端轉(zhuǎn)移到了服務(wù)端

WebSocket是HTML5中提出的一個(gè)新標(biāo)準(zhǔn)(也可視之為協(xié)議),客戶端在發(fā)送請(qǐng)求時(shí)在請(qǐng)求頭加入額外的字段,以標(biāo)識(shí)這是一個(gè)基于WebSocket協(xié)議的連接,服務(wù)器根據(jù)這個(gè)請(qǐng)求頭生成響應(yīng),與客戶端建立起WebSocket連接,之后服務(wù)端有新消息時(shí),直接向客戶端推送即可

不同瀏覽器兼容性

chrome采用的推送服務(wù)器為gcm或fcm,firefox也有自己的推送服務(wù)器

uc前些時(shí)間構(gòu)建了自己的推送服務(wù)器,引入其官網(wǎng)上的sdk包,申請(qǐng)使用后即可用于開(kāi)發(fā)

大家要是感興趣可以看看我的github~https://github.com/proempire,這個(gè)項(xiàng)目可能會(huì)繼續(xù)跟進(jìn)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107097.html

相關(guān)文章

  • 【PWA學(xué)習(xí)與實(shí)踐】(5)在Web中進(jìn)行服務(wù)端消息推送

    摘要:本文是學(xué)習(xí)與實(shí)踐系列的第五篇文章。實(shí)際上,消息推送與提醒是兩個(gè)功能和。在這一篇里,我們先來(lái)學(xué)習(xí)如何使用進(jìn)行消息推送。而當(dāng)服務(wù)端要推送消息時(shí),會(huì)使用私鑰對(duì)發(fā)送的數(shù)據(jù)進(jìn)行數(shù)字簽名,并根據(jù)數(shù)字簽名生成一個(gè)叫請(qǐng)求頭。 《PWA學(xué)習(xí)與實(shí)踐》系列文章已整理至gitbook - PWA學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至learning-pwa-ebook。轉(zhuǎn)載請(qǐng)注明作者與出處。 本文是《PWA學(xué)習(xí)與實(shí)踐》系...

    suemi 評(píng)論0 收藏0
  • Android 性能監(jiān)控系列一(原理篇)

    摘要:全稱應(yīng)用性能管理監(jiān)控后面我會(huì)通過(guò)一系列的文章來(lái)介紹的原理框架設(shè)計(jì)與實(shí)現(xiàn)等等。在應(yīng)用構(gòu)建期間,通過(guò)修改字節(jié)碼的方式來(lái)進(jìn)行字節(jié)碼插樁就是實(shí)現(xiàn)自動(dòng)化的方案之一。 showImg(https://segmentfault.com/img/bVbbRX6?w=1995&h=1273); 歡迎關(guān)注微信公眾號(hào):BaronTalk,獲取更多精彩好文! 一. 前言 性能問(wèn)題是導(dǎo)致 App 用戶流失的罪魁...

    yacheng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<