iT邦幫忙

2022 iThome 鐵人賽

DAY 7
1
Modern Web

這些那些你可能不知道我不知道的Web技術細節系列 第 7

你可能不知道的即時更新方案:Polling

靜態網頁 & 動態網頁

全球資訊網路(World Wide Web, WWW)最早用於學術研究機構,用於分享研究報告成果。起初常見型態為:資訊分享者自行建立Web伺服器,提供HTML靜態頁面,讓資訊受者透過瀏覽器取得資訊。

英國科學家提姆·柏內茲-李於1989年發明了全球資訊網。1990年他在瑞士CERN的工作期間編寫了第一個網頁瀏覽器。網頁瀏覽器於1991年1月向其他研究機構發行,並於同年8月向公眾開放。^1

「資訊分享者自行建立Web伺服器,提供HTML靜態頁面,讓資訊受者透過瀏覽器取得資訊」這從現在來看,可能分成兩個不同維度的類型:

  1. Web 1.0: 資訊分享者自行建立Web伺服器。用戶只能單向被動的接受由權威內容服務提供商提供的內容,用戶大部分為內容消費者,而網站則由內容驅動^2
  2. 靜態內容網頁。網頁內容並不會因為內容接收者的不同、時間地區的不同而有所不同。

隨後出現部落格平台、線上論壇,出現可以提供資訊內容的網站使用者。在此,網站內容不再簡單以HTMl方式儲存,更多的內容儲存於資料庫,由使用者提供,動態的提供給瀏覽器。這是 動態網頁Web 2.0

此外伴隨者瀏覽器腳本語言與API的逐漸統一,確立了 ECMAScript / JavaScript 在瀏覽器的地位,結束了過往百家爭鳴的情況(不過現在還有一些原生支援特殊腳本語言的瀏覽器存在,但JavaScript已成主流)。
似動非動,吸引人眼球由JS、CSS建立動畫效果的網頁內容開始玲瑯滿目地出現。

1996年11月,網景正式向ECMA(歐洲電腦製造商協會)提交語言標準。1997年6月,ECMA以JavaScript語言為基礎制定了ECMAScript標準規範ECMA-262。JavaScript成為了ECMAScript最著名的實現之一。除此之外,ActionScript和JScript也都是ECMAScript規範的實作語言。^3

其中也還有另一個令人興奮、今天廣泛使用的技術出現: Ajax(Asynchronous JavaScript and XML)

在現今,Ajax技術主要以XMLHttpRequestfetch兩個API呈現。也可能隱藏在jQuery^4Axios等比較高層次的套件函式庫之下。

這也使得由瀏覽器處理、在前端渲染生成不同內容的畫面成為可能。儘管這不是當前唯一的技術方式,但有許多別具特色的功能、前後分離的網站都依賴者這項能力。

接著就讓我們來探索幾個取得更新資訊的模式吧!

前端頁面內容即時更新方案

並非由後端伺服器選染產生HTML畫面的做法^5,主要分有Polling、Long Polling、Websocket還有WebRTC。此外還有比要少見的Server Send Event和multipart/x-mixed-replace這兩種處理方式。

  1. Polling
  2. Long Polling
  3. WebSocket
  4. Server Push / Server Send Event
  5. multipart/x-mixed-replace

本小節除了WebRTC,會探索一下其他的做法。

Polling

Polling輪詢。是一種透過Ajax技術不斷去取得新內容的方式。透過Ajax發出的Request和得到的Response遵循著通常的狀態,正常內容會在一定時間內返回,否則視為超時(timeout)。

返回內容依據需求實現。若資源沒有更新,回傳空內容或是舊內容;否則回傳新內容。

實際上超時對於應用整體而言也沒什麼影響,因爲會在下一次取得新的內容。通常而言,在取得內容後也不會立刻再詢問一次新內容。視需要即時更新的情況與內容通常更新的情況,會設置一段間格時間。

由於實現簡單,目前還有不少設計可以見得其身影。

優點

對於一般的Web架構來說,後端架構幾乎無需調整。前端視需要即時更新的情況與內容通常更新的情況,決定何時需要取得新的內容資訊。是由前端,需要呈現資料的一方主動拉取。

缺點

內容並非即時。由於是由前端主動詢問拉取的,而且通常而言每次詢問間會有一段間格時間。這段間格時間並不保持雙方連線。因此可能存在資料內容不即時的問題。

此外,由於每次Request可能都是獨立的TCP連線,因此都需要經過TCP的三段式交握連線。這段於網絡消耗而言是而外的看不見的負擔。

這是發生在TCP協議上。HTTP/0.9、HTTP/1.0、HTTP/2.0 都是基於 TCP ,可能發生這個情況。但是 HTTP/3 是基於QUIC,而該是基於UDP下的,可能就沒有影響。

Lab

由於Polling非常簡單,因此實驗環境需求也非常簡單。

這裡將透過docker建立一個Nginx服務器。
如果你安裝了Python,也可以透過python -m http.server執行Python自帶的簡易伺服器。

收先先建立www-data的資料夾。然後透過docker啓動Nginx:

docker run --name nginx --rm -p 8080:80 -v "${PWD}/www-data":/usr/share/nginx/html nginx

www-data資料夾下建立一份content.txt,並寫入Hello World的內容。

若資源沒有更新,回傳空內容或是舊內容

對於沒有更新的資源內容,將會回傳就有的內容。因此前端顯式時只需要每次都取代原本顯式內書仍即可。

然後同樣在www-data資料夾建立index.html:

<!-- www-data/index.html -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <title>即時更新內容 - Polling</title>
  </head>
  <body>
    <h1 id="content"></h1>
  </body>
  <script defer type="module">
   const delay = 5000/*ms*/;
   const contentEl = document.querySelector('#content');
   let timer = null;

   async function updateContent(){
       let response = await fetch('/content.txt')
       contentEl.innerText = await response.text();
       timer = setTimeout( updateContent , delay);
   }

   updateContent();

  </script>
</html>

現在,我們可以透過 http://localhost:8080 去瀏覽這個頁面。
這個頁面會每隔5秒去取得一次content.txt的內容,並顯示在畫面上。所以你可以將content.txt改成:

Hello Bob!

在5秒內,畫面應該就會更新成新的content.txt的內容。

參考資料

本文同時發表於我的隨筆


上一篇
你可能不知道URL的路徑編碼Percent-encoding
下一篇
你可能不知道的即時更新方案:Long Polling
系列文
這些那些你可能不知道我不知道的Web技術細節33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
lagagain
iT邦新手 2 級 ‧ 2022-09-23 06:58:41

Server Push / Server Send Event

雖然我這裡把 Server Push 和 Server Send Event 放在一起,但是兩者是完全不同的技術。之後會說道 Server Send Event(SSE) 。至於 Server Push ,實話說我並沒有很了解,能否做到類似的功能對我來說還是未知。只是因爲兩個從命名和行爲模式很像,一開始我也沒有弄得很清楚。

我要留言

立即登入留言