成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

介紹一下漸進(jìn)式 Web App(消息推送) - Part 3

vslam / 3090人閱讀

摘要:在的的監(jiān)聽(tīng)事件下,可以接收任何傳入的消息。這個(gè)也將負(fù)責(zé)向已激活推送消息的所有用戶(hù)發(fā)送消息。上面的代碼負(fù)責(zé)彈出請(qǐng)求用戶(hù)是否允許或阻止瀏覽器中的推送消息。這個(gè)處理了保存和刪除訂閱同時(shí)也處理了消息推送的功能。我們將使用作為我們的消息服務(wù)。

在第一篇:介紹一下漸進(jìn)式 Web App(離線(xiàn)) - Part 1中我們介紹了一個(gè)典型的PWA應(yīng)該是什么樣子的,并且介紹了一下sercer worker和應(yīng)用殼(app shell),在第二篇[介紹一下漸進(jìn)式 Web App(即時(shí)加載) - Part 2
](https://juejin.im/post/5a3245...,我們緩存了動(dòng)態(tài)數(shù)據(jù),并實(shí)現(xiàn)了從本地保存的數(shù)據(jù)中即時(shí)加載數(shù)據(jù)到頁(yè)面中,也順便介紹了web的一些數(shù)據(jù)庫(kù)。

這篇文章也是這系列的完結(jié)篇,我們將實(shí)現(xiàn):

在Web應(yīng)用程序中激活推送通知

使Web應(yīng)用程序的變成是可以可安裝的

消息推送

push API使Web應(yīng)用程序能夠接收從服務(wù)器推送來(lái)的消息并通知用戶(hù)。這個(gè)功能需要service worker配合起來(lái),在Web應(yīng)用程序中典型的推送通知流程的過(guò)程是這樣子滴:

Web應(yīng)用程序彈出一個(gè)彈出窗口,要求用戶(hù)訂閱通知。

用戶(hù)訂閱接收推送通知。

service worker 負(fù)責(zé)管理、處理用戶(hù)的訂閱。

當(dāng)服務(wù)器推送消息時(shí)都會(huì)用到用戶(hù)訂閱的ID,每個(gè)用戶(hù)根據(jù)他們的訂閱ID都可以有一個(gè)自定義的功能。

在service worker的push的監(jiān)聽(tīng)事件下,可以接收任何傳入的消息。

讓我們開(kāi)始吧。

我們先快速總結(jié)一下,消息推送時(shí)怎么在我們的web app中實(shí)現(xiàn)的

給用戶(hù)一個(gè)開(kāi)關(guān),單擊一個(gè)按鈕激活或停用推送通知。

如果用戶(hù)激活,請(qǐng)訂閱用戶(hù)通過(guò)service worker的管理接收推送通知。

構(gòu)建一個(gè)API 去處理用戶(hù)刪除或者保存訂閱ID。這個(gè)API也將負(fù)責(zé)向已激活推送消息的所有用戶(hù)發(fā)送消息。

建立一個(gè)GitHub Webhook去實(shí)現(xiàn)立即發(fā)送通知,讓新的提交被推送到resources-i-like倉(cāng)庫(kù)

代碼行動(dòng)起來(lái)

在項(xiàng)目中新建js/notification.js文件,并且在index.html中引用。


js/notification.js 代碼如下
(function (window) {
  "use strict";

  //Push notification button
  var fabPushElement = document.querySelector(".fab__push");
  var fabPushImgElement = document.querySelector(".fab__image");

  //To check `push notification` is supported or not
  function isPushSupported() {
    //To check `push notification` permission is denied by user
    if (Notification.permission === "denied") {
      alert("User has blocked push notification.");
      return;
    }

    //Check `push notification` is supported or not
    if (!("PushManager" in window)) {
      alert("Sorry, Push notification isn"t supported in your browser.");
      return;
    }

    //Get `push notification` subscription
    //If `serviceWorker` is registered and ready
    navigator.serviceWorker.ready
      .then(function (registration) {
        registration.pushManager.getSubscription()
        .then(function (subscription) {
          //If already access granted, enable push button status
          if (subscription) {
            changePushStatus(true);
          }
          else {
            changePushStatus(false);
          }
        })
        .catch(function (error) {
          console.error("Error occurred while enabling push ", error);
        });
      });
  }

  // Ask User if he/she wants to subscribe to push notifications and then 
  // ..subscribe and send push notification
  function subscribePush() {
    navigator.serviceWorker.ready.then(function(registration) {
      if (!registration.pushManager) {
        alert("Your browser doesn"t support push notification.");
        return false;
      }

      //To subscribe `push notification` from push manager
      registration.pushManager.subscribe({
        userVisibleOnly: true //Always show notification when received
      })
      .then(function (subscription) {
        toast("Subscribed successfully.");
        console.info("Push notification subscribed.");
        console.log(subscription);
        //saveSubscriptionID(subscription);
        changePushStatus(true);
      })
      .catch(function (error) {
        changePushStatus(false);
        console.error("Push notification subscription error: ", error);
      });
    })
  }

  // Unsubscribe the user from push notifications
  function unsubscribePush() {
    navigator.serviceWorker.ready
    .then(function(registration) {
      //Get `push subscription`
      registration.pushManager.getSubscription()
      .then(function (subscription) {
        //If no `push subscription`, then return
        if(!subscription) {
          alert("Unable to unregister push notification.");
          return;
        }

        //Unsubscribe `push notification`
        subscription.unsubscribe()
          .then(function () {
            toast("Unsubscribed successfully.");
            console.info("Push notification unsubscribed.");
            console.log(subscription);
            //deleteSubscriptionID(subscription);
            changePushStatus(false);
          })
          .catch(function (error) {
            console.error(error);
          });
      })
      .catch(function (error) {
        console.error("Failed to unsubscribe push notification.");
      });
    })
  }

  //To change status
  function changePushStatus(status) {
    fabPushElement.dataset.checked = status;
    fabPushElement.checked = status;
    if (status) {
      fabPushElement.classList.add("active");
      fabPushImgElement.src = "../images/push-on.png";
    }
    else {
     fabPushElement.classList.remove("active");
     fabPushImgElement.src = "../images/push-off.png";
    }
  }

  //Click event for subscribe push
  fabPushElement.addEventListener("click", function () {
    var isSubscribed = (fabPushElement.dataset.checked === "true");
    if (isSubscribed) {
      unsubscribePush();
    }
    else {
      subscribePush();
    }
  });

  isPushSupported(); //Check for push notification support
})(window);

上面的代碼做了很多事情。放心啦,我將會(huì)解釋一波代碼的功能滴。

//Push notification button
  var fabPushElement = document.querySelector(".fab__push");
  var fabPushImgElement = document.querySelector(".fab__image");

上面的代碼獲取推送通知激活和停用按鈕的節(jié)點(diǎn)。

function isPushSupported() {
    //To check `push notification` permission is denied by user
    if (Notification.permission === "denied") {
      alert("User has blocked push notification.");
      return;
    }

    //Check `push notification` is supported or not
    if (!("PushManager" in window)) {
      alert("Sorry, Push notification isn"t supported in your browser.");
      return;
    }

    //Get `push notification` subscription
    //If `serviceWorker` is registered and ready
    navigator.serviceWorker.ready
      .then(function (registration) {
        registration.pushManager.getSubscription()
        .then(function (subscription) {
          //If already access granted, enable push button status
          if (subscription) {
            changePushStatus(true);
          }
          else {
            changePushStatus(false);
          }
        })
        .catch(function (error) {
          console.error("Error occurred while enabling push ", error);
        });
      });
  }

上面的代碼是檢查瀏覽器以是否支持推送通知?,F(xiàn)在,最重要的是 service worker 必須注冊(cè)并且在您嘗試訂閱用戶(hù)以接收推送通知之前,已經(jīng)做好了準(zhǔn)備(ready)。因此,上面的代碼也檢查service worker是否ready并獲得用戶(hù)的訂閱。

 //To change status
  function changePushStatus(status) {
    fabPushElement.dataset.checked = status;
    fabPushElement.checked = status;
    if (status) {
      fabPushElement.classList.add("active");
      fabPushImgElement.src = "../images/push-on.png";
    }
    else {
     fabPushElement.classList.remove("active");
     fabPushImgElement.src = "../images/push-off.png";
    }
  }

用戶(hù)訂閱按鈕的樣式改變

changePushStatus函數(shù)代表著只需更改按鈕的顏色來(lái)指示用戶(hù)是否已訂閱。

// Ask User if he/she wants to subscribe to push notifications and then 
  // ..subscribe and send push notification
  function subscribePush() {
    navigator.serviceWorker.ready.then(function(registration) {
      if (!registration.pushManager) {
        alert("Your browser doesn"t support push notification.");
        return false;
      }

      //To subscribe `push notification` from push manager
      registration.pushManager.subscribe({
        userVisibleOnly: true //Always show notification when received
      })
      .then(function (subscription) {
        toast("Subscribed successfully.");
        console.info("Push notification subscribed.");
        console.log(subscription);
        //saveSubscriptionID(subscription);
        changePushStatus(true);
      })
      .catch(function (error) {
        changePushStatus(false);
        console.error("Push notification subscription error: ", error);
      });
    })
  }

上面的代碼負(fù)責(zé)彈出請(qǐng)求用戶(hù)是否允許或阻止瀏覽器中的推送消息。如果用戶(hù)允許推送消息,就是彈出一個(gè)toast的已經(jīng)允許的提示,然后更改按鈕的顏色并保存訂閱ID。如果推瀏覽器不支持,那么它會(huì)通知用戶(hù)它不受支持。

注意:保存訂閱ID的功能現(xiàn)在已被注釋掉。

// Unsubscribe the user from push notifications
  function unsubscribePush() {
    navigator.serviceWorker.ready
    .then(function(registration) {
      //Get `push subscription`
      registration.pushManager.getSubscription()
      .then(function (subscription) {
        //If no `push subscription`, then return
        if(!subscription) {
          alert("Unable to unregister push notification.");
          return;
        }

        //Unsubscribe `push notification`
        subscription.unsubscribe()
          .then(function () {
            toast("Unsubscribed successfully.");
            console.info("Push notification unsubscribed.");
            //deleteSubscriptionID(subscription);
            changePushStatus(false);
          })
          .catch(function (error) {
            console.error(error);
          });
      })
      .catch(function (error) {
        console.error("Failed to unsubscribe push notification.");
      });
    })
  }

上面的是負(fù)責(zé)退訂推送消息,彈出一個(gè)toast提示小心,然后更改按鈕的顏色并刪除訂閱ID。

注意:刪除訂閱ID的功能現(xiàn)在已被注釋掉了。

 //Click event for subscribe push
  fabPushElement.addEventListener("click", function () {
    var isSubscribed = (fabPushElement.dataset.checked === "true");
    if (isSubscribed) {
      unsubscribePush();
    }
    else {
      subscribePush();
    }
  });

上面代碼是添加一個(gè)按鈕單擊事件實(shí)現(xiàn)訂閱和取消訂閱用戶(hù)的切換。

處理訂閱ID

我們已經(jīng)能夠看到推送訂閱了。現(xiàn)在,我們需要能夠保存每個(gè)用戶(hù)的訂閱ID,當(dāng)用戶(hù)退訂的推送通知時(shí)我們還需要能夠刪除這些訂閱ID。

添加下面的代碼到你的js/notification.js

function saveSubscriptionID(subscription) {
    var subscription_id = subscription.endpoint.split("gcm/send/")[1];

    console.log("Subscription ID", subscription_id);

    fetch("http://localhost:3333/api/users", {
      method: "post",
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ user_id : subscription_id })
    });
}

function deleteSubscriptionID(subscription) {
    var subscription_id = subscription.endpoint.split("gcm/send/")[1];

    fetch("http://localhost:3333/api/user/" + subscription_id, {
      method: "delete",
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/json"
      }
    });
}

在上面的代碼中,我們從服務(wù)器請(qǐng)求一個(gè)接口,來(lái)獲取訂閱ID和和刪除訂閱ID,saveSubscriptionID函數(shù)創(chuàng)建了一個(gè)新的用戶(hù)并且保存了用戶(hù)的訂閱ID,deleteSubscriptionID刪除了用戶(hù)和用戶(hù)的訂閱ID

看起來(lái)怪怪的。為什么要請(qǐng)求到服務(wù)器?簡(jiǎn)單,因?yàn)槲覀冃枰粋€(gè)數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)所有的訂閱ID,這樣子就可以向所有的用戶(hù)發(fā)送消息推送。

API Service

這個(gè)API Service 處理了保存和刪除訂閱ID同時(shí)也處理了消息推送的功能。這API的分解。它將有3個(gè)api路由:

POST /api/users創(chuàng)建新用戶(hù)并存儲(chǔ)其訂閱ID

DELETE /api/user/:user_id刪除和取消訂閱用戶(hù)

POST /api/notify向所有訂閱用戶(hù)發(fā)送通知

很高興,我有API Service的源碼,道友可以點(diǎn)擊鏈接查看,運(yùn)行時(shí)候確保你的nodemongodb是事先安裝過(guò)的??寺i下來(lái)并且在命令行中運(yùn)行node server.js

確保你先創(chuàng)建.env文件,如下圖所示

溫馨提醒:您可以通過(guò)這個(gè)良好的教程去了解如何設(shè)置API服務(wù)。在本教程我只是實(shí)現(xiàn)了node.js版本的API服務(wù)。

我們將使用Firebase Cloud Messaging 作為我們的消息服務(wù)。所以,現(xiàn)在用Firebase去建立一個(gè)新的項(xiàng)目。新建項(xiàng)目完了之后就去Project settings > Cloud Messaging這里

拿到你的 Server Key然后復(fù)制粘貼到你的.env文件在的FCM_API_KEY,通過(guò)我們的API Server我們需要將Server Key傳給Firebase,下面看看我們的看看我們的消息推送控制器的代碼:

....

notifyUsers: function(req, res){

    var sender = new gcm.Sender(secrets.fcm);

    // Prepare a message to be sent
    var message = new gcm.Message({
        notification: {
          title: "New commit on Github Repo: RIL",
          icon: "ic_launcher",
          body: "Click to see the latest commit""
        }
    });

    User.find({}, function(err, users) {

      // user subscription ids to deliver message to
      var user_ids = _.map(users, "user_id");

      console.log("User Ids", user_ids);

      // Actually send the message
      sender.send(message, { registrationTokens: user_ids }, function (err, response) {
        if (err) {
            console.error(err);
        } else {
          return res.json(response);
        } 
      });
    });

  },

  .....

現(xiàn)在返回我們的js/notification.js并且去掉我們之前說(shuō)的saveSubscriptionID函數(shù)和deleteSubscriptionID的注釋?zhuān)缓竽愕?b>notification.js應(yīng)該是長(zhǎng)這樣子滴:

(function (window) {
  "use strict";

  //Push notification button
  var fabPushElement = document.querySelector(".fab__push");
  var fabPushImgElement = document.querySelector(".fab__image");

  //To check `push notification` is supported or not
  function isPushSupported() {
    //To check `push notification` permission is denied by user
    if (Notification.permission === "denied") {
      alert("User has blocked push notification.");
      return;
    }

    //Check `push notification` is supported or not
    if (!("PushManager" in window)) {
      alert("Sorry, Push notification isn"t supported in your browser.");
      return;
    }

    //Get `push notification` subscription
    //If `serviceWorker` is registered and ready
    navigator.serviceWorker.ready
      .then(function (registration) {
        registration.pushManager.getSubscription()
        .then(function (subscription) {
          //If already access granted, enable push button status
          if (subscription) {
            changePushStatus(true);
          }
          else {
            changePushStatus(false);
          }
        })
        .catch(function (error) {
          console.error("Error occurred while enabling push ", error);
        });
      });
  }

  // Ask User if he/she wants to subscribe to push notifications and then 
  // ..subscribe and send push notification
  function subscribePush() {
    navigator.serviceWorker.ready.then(function(registration) {
      if (!registration.pushManager) {
        alert("Your browser doesn"t support push notification.");
        return false;
      }

      //To subscribe `push notification` from push manager
      registration.pushManager.subscribe({
        userVisibleOnly: true //Always show notification when received
      })
      .then(function (subscription) {
        toast("Subscribed successfully.");
        console.info("Push notification subscribed.");
        console.log(subscription);
        saveSubscriptionID(subscription);
        changePushStatus(true);
      })
      .catch(function (error) {
        changePushStatus(false);
        console.error("Push notification subscription error: ", error);
      });
    })
  }

  // Unsubscribe the user from push notifications
  function unsubscribePush() {
    navigator.serviceWorker.ready
    .then(function(registration) {
      //Get `push subscription`
      registration.pushManager.getSubscription()
      .then(function (subscription) {
        //If no `push subscription`, then return
        if(!subscription) {
          alert("Unable to unregister push notification.");
          return;
        }

        //Unsubscribe `push notification`
        subscription.unsubscribe()
          .then(function () {
            toast("Unsubscribed successfully.");
            console.info("Push notification unsubscribed.");
            console.log(subscription);
            deleteSubscriptionID(subscription);
            changePushStatus(false);
          })
          .catch(function (error) {
            console.error(error);
          });
      })
      .catch(function (error) {
        console.error("Failed to unsubscribe push notification.");
      });
    })
  }

  //To change status
  function changePushStatus(status) {
    fabPushElement.dataset.checked = status;
    fabPushElement.checked = status;
    if (status) {
      fabPushElement.classList.add("active");
      fabPushImgElement.src = "../images/push-on.png";
    }
    else {
     fabPushElement.classList.remove("active");
     fabPushImgElement.src = "../images/push-off.png";
    }
  }

  //Click event for subscribe push
  fabPushElement.addEventListener("click", function () {
    var isSubscribed = (fabPushElement.dataset.checked === "true");
    if (isSubscribed) {
      unsubscribePush();
    }
    else {
      subscribePush();
    }
  });

  function saveSubscriptionID(subscription) {
    var subscription_id = subscription.endpoint.split("gcm/send/")[1];

    console.log("Subscription ID", subscription_id);

    fetch("http://localhost:3333/api/users", {
      method: "post",
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ user_id : subscription_id })
    });
  }

  function deleteSubscriptionID(subscription) {
    var subscription_id = subscription.endpoint.split("gcm/send/")[1];

    fetch("http://localhost:3333/api/user/" + subscription_id, {
      method: "delete",
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/json"
      }
    });
  }

  isPushSupported(); //Check for push notification support
})(window);

讓我們嘗試激活消息推送,看看是否創(chuàng)建了新的用戶(hù),并存儲(chǔ)在我們的API服務(wù)數(shù)據(jù)庫(kù)中。重新刷新網(wǎng)頁(yè)并按下激活按鈕,然后看到控制臺(tái)居然有錯(cuò)誤。

別煩惱!著原因是我們沒(méi)有在我們的程序中創(chuàng)一個(gè)manifest.json 的文件。
現(xiàn)在有趣的事情是,添加上了manifest.json 的文件將不會(huì)報(bào)錯(cuò)并且在我們的程序中添加了一個(gè)新的功能。有了這個(gè)manifest.json 的文件,我們可以將我們的應(yīng)用程序安裝到我們的屏幕上。Viola?。?!

現(xiàn)在我們?nèi)?chuàng)建一個(gè)manifest.json 的文件吧,代碼如下

{
  "name": "PWA - Commits",
  "short_name": "PWA",
  "description": "Progressive Web Apps for Resources I like",
  "start_url": "./index.html?utm=homescreen",
  "display": "standalone",
  "orientation": "portrait",
  "background_color": "#f5f5f5",
  "theme_color": "#f5f5f5",
  "icons": [
    {
      "src": "./images/192x192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "./images/168x168.png",
      "type": "image/png",
      "sizes": "168x168"
    },
    {
      "src": "./images/144x144.png",
      "type": "image/png",
      "sizes": "144x144"
    },
    {
      "src": "./images/96x96.png",
      "type": "image/png",
      "sizes": "96x96"
    },
    {
      "src": "./images/72x72.png",
      "type": "image/png",
      "sizes": "72x72"
    },
    {
      "src": "./images/48x48.png",
      "type": "image/png",
      "sizes": "48x48"
    }
  ],
  "author": {
    "name": "Prosper Otemuyiwa",
    "website": "https://twitter.com/unicodeveloper",
    "github": "https://github.com/unicodeveloper",
    "source-repo": "https://github.com/unicodeveloper/pwa-commits"
  },
  "gcm_sender_id": "571712848651"
}

現(xiàn)在快速的掃盲一下manifest.json 上的key的含義吧。

name:表示應(yīng)用程序的名稱(chēng),因?yàn)樗ǔo@示在屏幕上給用戶(hù)看滴。

short_name:表示W(wǎng)eb應(yīng)用程序名稱(chēng)的縮寫(xiě)。

description:表示W(wǎng)eb應(yīng)用程序的一般描述。

start_url:是用戶(hù)啟動(dòng)Web應(yīng)用程序時(shí)加載的URL。

display:定義Web應(yīng)用程序的默認(rèn)顯示模式。不同的模式有fullscreen, standalone, minimal-ui

orientation:

background_color:表示W(wǎng)eb應(yīng)用程序的背景顏色。

theme_color:表示應(yīng)用程序的默認(rèn)主題顏色。它將Android上的狀態(tài)欄著色。

icons:主屏幕的icon圖標(biāo)

author:作者的一些信息

gcm_sender_id:用于識(shí)別應(yīng)用的Firebasesender_id,在下面取得。如下圖

在你的index.htmllatest.html引用這個(gè)manifest.json 文件。

 

現(xiàn)在,清楚緩存,刷新應(yīng)用,然后點(diǎn)擊消息推動(dòng)按鈕

然后看到 訂閱ID在控制臺(tái)中打印了出來(lái),查看下出數(shù)據(jù)庫(kù),

Yaaay!!,中于起作用了呢

在數(shù)據(jù)庫(kù)中你可以看到用戶(hù)的訂閱ID了,這意味著,我們的請(qǐng)求是成功滴

小提示:RoboMongo是一個(gè)管理mongodb數(shù)據(jù)庫(kù)的圖形界面。

您可以嘗試取消訂閱,查看它如何從API服務(wù)數(shù)據(jù)庫(kù)中刪除用戶(hù)。

發(fā)送和接收推送消息

在我們的service API中,我們做一個(gè)POST請(qǐng)求到/api/notify的路由,然后后臺(tái)接收到前端的請(qǐng)求繼續(xù)推送到Firebase Cloud Messaging 的服務(wù)中?,F(xiàn)在,這還是不夠滴,所以,我們還需要一種在瀏覽器中監(jiān)聽(tīng)和接受此通知的方法。

然后到Service Worker 閃亮登場(chǎng)了,用它來(lái)監(jiān)聽(tīng)一個(gè)push的事件,在sw.js中,代碼如下:


self.addEventListener("push", function(event) {

  console.info("Event: Push");

  var title = "New commit on Github Repo: RIL";

  var body = {
    "body": "Click to see the latest commit",
    "tag": "pwa",
    "icon": "./images/48x48.png"
  };

  event.waitUntil(
    self.registration.showNotification(title, body)
  );
});

這段代碼添加到sw.js。清緩存,重新加載你的應(yīng)用,現(xiàn)在我們利用postman去發(fā)起http://localhost:3333/api/notify請(qǐng)求

當(dāng)發(fā)出通知時(shí),我們的瀏覽器會(huì)歡迎這樣的通知:

接到通知后,當(dāng)用戶(hù)單擊這個(gè)通知時(shí),我們可以決定該怎么做。然后添加下面這個(gè)代碼到sw.js

self.addEventListener("notificationclick", function(event) {

  var url = "./latest.html";

  event.notification.close(); //Close the notification

  // Open the app and navigate to latest.html after clicking the notification
  event.waitUntil(
    clients.openWindow(url)
  );

});

這里,上面的代碼監(jiān)聽(tīng)用戶(hù)單擊通知時(shí)被觸發(fā)的事件。event.notification.close()是單擊后關(guān)閉通知。然后,將打開(kāi)一個(gè)瀏覽器新窗口或選項(xiàng)卡重新指向localhost:8080/latest.html地址。

提示:event.waitUntil()在我們的新窗口打開(kāi)之前,它就被調(diào)用了以確保瀏覽器不會(huì)終止我們的server worker。
自動(dòng)推送消息

之前我們是通過(guò)Postman手動(dòng)發(fā)起一個(gè)請(qǐng)求去推送消息的,實(shí)際上,我們是想,用于一旦有了提交到https://github.com/unicodeveloper/resources-i-like/,我們就自動(dòng)接收收到一個(gè)消息通知。那么,我們?nèi)绾问惯@個(gè)過(guò)程自動(dòng)化呢?

有聽(tīng)說(shuō)過(guò)Webhooks么???

有?。。?/p>

那么好~~我們就用GitHub Webhooks

提示: 使用您自己的倉(cāng)庫(kù)地址,因?yàn)榭吹搅诉@里,你就要自己提交commit了

到你選擇的倉(cāng)庫(kù)去,在這里我的是https://github.com/unicodeveloper/resources-i-like/,到 Settings > Webhooks中:

點(diǎn)擊add webhook添加一個(gè)hook,當(dāng)用戶(hù)提交的時(shí)候就觸發(fā)了pushs是事件,這個(gè)hook講通知我們的notify API ,利用這個(gè)webhook當(dāng)用戶(hù)提交commit時(shí)候,發(fā)出一個(gè)post請(qǐng)求到我們的/api/notify,然后順利成章的發(fā)送一個(gè)瀏覽器的消息推送啦。 開(kāi)森~~~~

看上面那個(gè)圖,慢著,等一下,是怎么得到https://ea71f5aa.ngrok.io/api/notifyz這個(gè)地址的??實(shí)際上是在本地開(kāi)發(fā)需要用ngrok工具,把內(nèi)網(wǎng)轉(zhuǎn)發(fā)出去。明白了吧

設(shè)置Ngrok

非常簡(jiǎn)單,我們不能使用localhost,GitHub上需要一個(gè)存在在網(wǎng)絡(luò)上URL,我利用ngrok可以將本地服務(wù)器暴露到Internet上。

安裝ngrok之后,在命令行中,敲上這樣子的代碼

./ngrok http 3333

得到

提示:ngrok輸出HTTP和HTTPS地址,它們都映射到本地服務(wù)。

現(xiàn)在,一旦你添加webhook,GitHub立即提交測(cè)試post請(qǐng)求來(lái)決定是否設(shè)置正確。

測(cè)試一個(gè)commit吧

我們把一切都做好了,現(xiàn)在我們?nèi)ヌ峤灰粋€(gè)commit,一旦你這么做了,一個(gè)消息推送就發(fā)送到我們的瀏覽器中了。 如下圖

Host PWA

一個(gè)PWA的要求服務(wù)是通過(guò)HTTPS的。用Firebase hosting部署我們的應(yīng)用程序服務(wù)器并且支持HTTPS協(xié)議是一個(gè)非常好的選擇。

我們app線(xiàn)上的地址:https://ril-pwa.firebaseapp.com/
服務(wù)器api線(xiàn)上地址:https://rilapi.herokuapp.com/api

添加應(yīng)用到主屏幕

打開(kāi)你的設(shè)備上的瀏覽器,尤其是Chrome,并像這樣添加它:

看到桌面上已經(jīng)有了 應(yīng)用圖標(biāo)了。然后本教程也是總結(jié)鳥(niǎo)。

~ 完結(jié),散花散花散花散花 ~~~~

附:

點(diǎn)擊鏈接查看

原文地址

第一篇: 介紹一下漸進(jìn)式 Web App(離線(xiàn)) - Part 1

第二篇: 介紹一下漸進(jìn)式 Web App(即時(shí)加載)- Part 2

項(xiàng)目PWA代碼

項(xiàng)目API code代碼

個(gè)人博客地址

如果有那個(gè)地方翻譯出錯(cuò)或者失誤,請(qǐng)各位大神不吝賜教,小弟感激不盡

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/92190.html

相關(guān)文章

  • [譯]介紹一下進(jìn)式 Web App(離線(xiàn)) - Part 1

    摘要:基本上是使用現(xiàn)代技術(shù)構(gòu)建的網(wǎng)站但是體驗(yàn)上卻像一個(gè)移動(dòng),在年,谷歌工程師和創(chuàng)造了。此后谷歌就一直致力于讓能給用戶(hù)像原生一般的體驗(yàn)。檢查谷歌瀏覽器的和現(xiàn)在重載你的并且打開(kāi),到選項(xiàng)去查看面板,確保這個(gè)選項(xiàng)是勾選的。 Web開(kāi)發(fā)多年來(lái)有了顯著的發(fā)展。它允許開(kāi)發(fā)人員部署網(wǎng)站或Web應(yīng)用程序并在數(shù)分鐘內(nèi)為全球數(shù)百萬(wàn)人服務(wù)。只需一個(gè)瀏覽器,用戶(hù)可以輸入U(xiǎn)RL就可以訪(fǎng)問(wèn)Web應(yīng)用程序了。隨著 Prog...

    gaara 評(píng)論0 收藏0
  • [譯]介紹一下進(jìn)式 Web App(離線(xiàn)) - Part 1

    摘要:基本上是使用現(xiàn)代技術(shù)構(gòu)建的網(wǎng)站但是體驗(yàn)上卻像一個(gè)移動(dòng),在年,谷歌工程師和創(chuàng)造了。此后谷歌就一直致力于讓能給用戶(hù)像原生一般的體驗(yàn)。檢查谷歌瀏覽器的和現(xiàn)在重載你的并且打開(kāi),到選項(xiàng)去查看面板,確保這個(gè)選項(xiàng)是勾選的。 Web開(kāi)發(fā)多年來(lái)有了顯著的發(fā)展。它允許開(kāi)發(fā)人員部署網(wǎng)站或Web應(yīng)用程序并在數(shù)分鐘內(nèi)為全球數(shù)百萬(wàn)人服務(wù)。只需一個(gè)瀏覽器,用戶(hù)可以輸入U(xiǎn)RL就可以訪(fǎng)問(wèn)Web應(yīng)用程序了。隨著 Prog...

    wenshi11019 評(píng)論0 收藏0
  • [譯]介紹一下進(jìn)式 Web App(離線(xiàn)) - Part 1

    摘要:基本上是使用現(xiàn)代技術(shù)構(gòu)建的網(wǎng)站但是體驗(yàn)上卻像一個(gè)移動(dòng),在年,谷歌工程師和創(chuàng)造了。此后谷歌就一直致力于讓能給用戶(hù)像原生一般的體驗(yàn)。檢查谷歌瀏覽器的和現(xiàn)在重載你的并且打開(kāi),到選項(xiàng)去查看面板,確保這個(gè)選項(xiàng)是勾選的。 Web開(kāi)發(fā)多年來(lái)有了顯著的發(fā)展。它允許開(kāi)發(fā)人員部署網(wǎng)站或Web應(yīng)用程序并在數(shù)分鐘內(nèi)為全球數(shù)百萬(wàn)人服務(wù)。只需一個(gè)瀏覽器,用戶(hù)可以輸入U(xiǎn)RL就可以訪(fǎng)問(wèn)Web應(yīng)用程序了。隨著 Prog...

    Wildcard 評(píng)論0 收藏0
  • [譯]介紹一下進(jìn)式 Web App(即時(shí)加載) - Part 2

    摘要:在上一篇,介紹一下漸進(jìn)式離線(xiàn)的文章中,我們討論了典型的應(yīng)該是什么樣子的并且同時(shí)也介紹了。暴露了一個(gè)異步,以避免阻塞的加載。但一些研究表明,在某些情況下,它是阻塞的。打開(kāi)并且添加如下代碼清除緩存并重新加載。 在上一篇,介紹一下漸進(jìn)式 Web App(離線(xiàn)) - Part 1的文章中,我們討論了典型的pwa應(yīng)該是什么樣子的并且同時(shí)也介紹了 server worker。到目前為止,我們已經(jīng)緩...

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

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

0條評(píng)論

閱讀需要支付1元查看
<