国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

web-push實現原理及細節介紹

hufeng / 2416人閱讀

摘要:一使用動機與原理簡述相較于移動端本地應用,站點常常缺少一項常用的功能推送通知。發送數據時,數據必須編碼出于安全性考慮。二實現細節按照上一部分所說,首先進行用戶訂閱。

一、web push 使用動機與原理簡述

相較于移動端本地應用,web站點常常缺少一項常用的功能:推送通知。此處的推送通知一般指由瀏覽器實現的消息推送,換個說法,就是用戶在打開瀏覽器時,不需要進入特定的網站,就能收到該網站推送而來的消息,例如:新評論,新動態等等。

那么web push究竟是怎樣的一個流程呢,簡單地說,可以分為三個步驟:

客戶端完成請求訂閱一個用戶的邏輯

服務端調用遵從web push協議的接口,傳送消息推送(push message)到推送服務器(該服務器由瀏覽器決定,開發者所能做的只有控制發送的數據)

推送服務器將該消息推送至對應的瀏覽器,用戶收到該推送

第一步,客戶端請求訂閱用戶,過程如下:

說明一下這三步,在第一步之前,應用服務器需要生成應用服務器密鑰(application server keys),其作用是標識該服務器,保證每次發消息推送的都是同一個服務器。然后,客戶端將會請求用戶授權消息推送,一旦用戶授權,瀏覽器就會生成一個PushScription,然后這個PushScription將會被發送至服務器,存入數據庫,在后面的消息推送中使用。

第二步,應用服務器發送web push協議標準的api,觸發推送服務器的消息推送,其中headers必須配置正確,且傳送的數據必須是比特流。

應用服務器發送消息推送請求(目的是為了將更新推送到用戶的瀏覽器),為了向推送服務器發出請求,需要查看先前獲得的PushScription,取出其中的endpoint,即為推送服務器配置給該用戶的訪問點。

一個PushScription對象如下:

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

其中的endpoint包含了推送服務器域名,path后面的部分為推送服務器為每個用戶分配的一個標識符。

發送數據時,數據必須編碼(出于安全性考慮)。推送服務器在接收到這樣一個請求之后,立即開始監聽用戶瀏覽器是否處于在線狀態,若是,則將消息推送發送至瀏覽器。

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

瀏覽器在接收到推送服務器發來的推送后,將其解碼并觸發一個push事件。Service Worker由于它可以在瀏覽器頁面未打開,瀏覽器未打開時執行,因此一般選擇它完成web push的最后一步,即響應push事件完成展示通知等業務邏輯。

二、web push實現細節

按照上一部分所說,首先進行用戶訂閱。

首先注冊一個Service Worker,若注冊成功,返回的Promise為resolve狀態,如下:

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);
  });
}

隨后測試window環境下是否有Notification對象(此處以chrome為例,若使用firefox,uc等瀏覽器,需要遵循其相應標準,調用對應對象方法或引入JS SDK包),測試成功,調用Notification.requestPermission請求用戶授權發送推送,若授權成功,將會返回"granted"。

接下來要做的就是使用注冊好的Service Worker對象,調用pushManager.subscribe方法,從客戶端獲得剛剛所說的PushScription對象。

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是為了保證推送對用戶可見,application server key則如前文所說,是推送服務器用以識別應用服務器的密鑰,這里的密鑰包含了公鑰和私鑰,傳輸的是公鑰。同時,PushScription的endpoint也是在這個過程中生成的,生成公鑰和私鑰可以使用web-push庫。

這里再次說明一下推送服務器的不可選擇性,在調用subscribe生成PushScription時,瀏覽器會向它指定的中轉服務器發送請求來生成endpoint和其余部分,這是沒法控制的。

PushScription中的auth和p256dh是用來控制帶載荷的push message的。

獲取到PushScription對象后,將其發往應用服務器,此處簡化了存儲,使用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);
    });
  });
};

存儲完畢后,接下來就是開發后臺管理邏輯,使得管理員能夠觸發向用戶推送消息的事件,應用服務器所做的邏輯就是遍歷在數據庫中存儲的所有PushScription并推送消息,以下是使用web-push庫完成配置密鑰及聯系郵箱的示例:

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

webpush.setVapidDetails(
  "mailto:web-push-book@gauntface.com",
  vapidKeys.publicKey,
  vapidKeys.privateKey
);

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

webpush.setGCMAPIKey("");

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

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

推送服務器發送消息后,會觸發瀏覽器的push事件,為了控制service worker的邏輯,需要使用event.waitUntil方法,此方法接收一個promise參數,在promise變為resolved狀態后,瀏覽器就會檢查通知是否已被展示,若是,則關閉service worker。

如果不處理未正常執行的promise,部分瀏覽器如chrome會展示默認消息框:

展示一個通知調用的為showNotification方法,傳的參數包括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時,除了控制它的視圖層以外,也可以控制它的邏輯層,例如點擊消息通知后進行某些操作等等,在先前調用showNotification時可以傳入一些參數,例如,根據不同的action執行不同的操作:

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;
  }
});
三、兼容性及其他問題 與ajax輪詢、http長連接、WebSocket的對比

ajax輪詢是通過客戶端不斷向服務端發送http請求,若有新消息就取回的模式保持數據實時更新,但這種方式需要服務器有很快的處理速度和資源

http長連接是客戶端向服務器發送請求后,若服務器沒有新數據要發送,就不返回response,一旦有了新數據返回了response,客戶端就立刻再發一個request,周而復始。事實上這是把http協議的不對稱性從客戶端轉移到了服務端

WebSocket是HTML5中提出的一個新標準(也可視之為協議),客戶端在發送請求時在請求頭加入額外的字段,以標識這是一個基于WebSocket協議的連接,服務器根據這個請求頭生成響應,與客戶端建立起WebSocket連接,之后服務端有新消息時,直接向客戶端推送即可

不同瀏覽器兼容性

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

uc前些時間構建了自己的推送服務器,引入其官網上的sdk包,申請使用后即可用于開發

大家要是感興趣可以看看我的github~https://github.com/proempire,這個項目可能會繼續跟進

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107097.html

相關文章

  • 【PWA學習與實踐】(5)在Web中進行服務端消息推送

    摘要:本文是學習與實踐系列的第五篇文章。實際上,消息推送與提醒是兩個功能和。在這一篇里,我們先來學習如何使用進行消息推送。而當服務端要推送消息時,會使用私鑰對發送的數據進行數字簽名,并根據數字簽名生成一個叫請求頭。 《PWA學習與實踐》系列文章已整理至gitbook - PWA學習手冊,文字內容已同步至learning-pwa-ebook。轉載請注明作者與出處。 本文是《PWA學習與實踐》系...

    suemi 評論0 收藏0
  • Android 性能監控系列一(原理篇)

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

    yacheng 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<