跳到主要內容

【Web微知識系列】雙向溝通的技術,什麼是Websocket?

 

進入本篇章前建議您可以先了解以下兩個篇章,主要是介紹單向過程中的訂閱概念:

這種雙向溝通機制主要是為了更即時的反應,舉例來說今天我們有一個應用是即時語音辨識,那麼勢必會有一個互動的過程,使用者端進行錄音後,即時的送到伺服器進行辨識並將辨識結果即時呈現於畫面上時,就必須透過這種雙向溝通機制才能完成。

簡介

傳統的Http是一種Stateless的傳輸方式, 因此不會維持原本狀態, 而是需要更新、新增、查詢...等操作時才進行請求, 因此假設有即時性互動的應用時就不太適用了, 因為每進行一個動作就要向Server端發送請求, 而每次的請求都必須經過交握式連接的過程, 在效能上就不是那麼理想了, Websocket允許瀏覽器跟Server端只經過一次的交握過程, 就能建立一條長連接的溝通管道, 並透過這條管道進行「雙向傳輸」。

Websocket與TCP、HTTP的關係

  • Websocket與HTTP屬於應用層, 同樣都是基於TCP來進行傳輸, 而進行Handshake時也會透過HTTP進行, 但真正傳輸資料時就不必經過HTTP的方式。


  • 與HTTP一樣可以進行加密傳輸, HTTP的部份為https, Websocket則為wss


為什麼要使用Websocket?

其實以往我們網頁資料刷新有以下幾種方式可以實作:

Polling

這種方式是早期透過Javascript定時(setIntervalsetTimeout)來向後端請求最新資料並呈現於頁面之上, 這麼做的好處是容易實現, 但我們並不知曉Server端何時會更新, 只能傻傻的定時獲取, 造成的影響就是頻寬的浪費以及資料呈現不即時。



Long-Polling

長時間輪詢的方式就是收到前端請求後, Server端會等待, 若這段時間有資料就會將最新資料回傳給前端, 因此等待的這段期間Client什麼事情也不用做, 等待資料回傳後再發送下一個請求, 雖然長時間的連接解決了Polling開銷的問題, 但如果在更新資料很頻繁的狀況下也會造成連續的Polling的動作產生, 未必效能較佳。



Server Sent Events

這種方式比較少被使用, 因為SSE能做的功能Websocket也能完成, 差別只是雙向溝通還是單向溝通而已, 不過在某些應用上, 瀏覽器不太需要傳遞資料給Server端, 例如: 股市行情、即時新聞...等, 只需要接收Server端的最新資料即可, 不太需要主動發送, 當然實作起來也較容易, 簡單來說就是伺服端單向的推送資料給瀏覽器。



Websocket

以上幾個方式的共同點就是都基於HTTP進行傳輸, 而我們也知道HTTP的傳輸為了確保正確性會帶有較多的標頭...等資訊, 而Websocket只有一開始確定連線時會走HTTP以外, 之後的傳輸都不是基於HTTP, 因此傳輸上會來的更有效率, 且提供了雙向溝通的功能。



常見的線上互動遊戲、雲端協作、線上聊天...等, 若使用上述的幾種方式都有延遲的議題存在,因此需要即時互動的應用就非常適合使用Websocket的方式來進行實作。

建立連接

  • 以javascript來說, 通常我們在建立Websocket物件的時候, Browser就開始進行Handshake的過程。
var socket = new WebSocket("ws://127.0.0.1:8080/ws")
  • 建立連線成功後,會發送支援的版本號、主機地址...等資訊給Server端。
Accept-Encoding: gzip, deflate

Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7

Cache-Control: no-cache

Connection: Upgrade

Host: 127.0.0.1:8080

Origin: http:*//127.0.0.1:8080*

Pragma: no-cache

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

Sec-WebSocket-Key: sZrnswRjM0ZXxxmAIJhrvQ==

Sec-WebSocket-Version: 13

Upgrade: websocket

User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36
  • Server端收到後會回傳狀態碼101及相關資訊。
HTTP/1.1 101 Switching Protocols

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Accept: 3zg/SIKvYpT51lJJKbF4WjFuCTY=

Access-Control-Allow-Origin: *

Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization
  • 如果過程失敗的話就會進入onerror的handler, 成功的話就代表可以開始傳輸資料。

如何確保連線狀態

假設連線的過程中發生了以下兩種狀況:

  1. 長時間不發送訊息或者防火牆阻擋了連接, Server端無法得知。
  2. Client端與Server端之間斷開網路, Server端也未感知。

此時就需要一種Heartbeat的機制, 來偵測彼此的連線是否存活。

  1. 由發送端發送ping訊號給接收端。
  2. 接收端成功收到之後, 回應pong訊號給發送端。
  3. 成功接收到pong訊號, 代表連線正常。
發送端 -> ping -> 接收端

發送端 <- pong <- 接收端

對於Client端來說就有開發者提供了Heartbeat的套件websocket-heartbeat-js, 讓我們開發前端時省去自行實做的時間。

📝 Web微知識系列文章


喜歡撰寫文章的你,不妨來了解一下:

Web3.0時代下為創作者、閱讀者打造的專屬共贏平台 - 為什麼要加入?

歡迎加入一起練習寫作,賺取知識,累積財富!

⭐ 跟著「阿Han」一起來閱讀、撰寫文章,讓知識變現吧! ⭐

💬 如果您有任何問題,也歡迎底下留言告訴我,讓我們一起學習 💬

📚 如果想看更多精選文章,或者關於我的相關資訊請來這裡...

留言

這個網誌中的熱門文章

java西元民國轉換_各種不同格式

C#資料庫操作(新增、修改、刪除、查詢)

【Excel好好玩】 自己的資產自己管!善用Google Sheet來幫我們評估貸款

這次介紹的主題是關於Excel的貸款還款計畫試算,我們人生中總會遇到需要大筆金額的花費,但當資金不夠時就得進行貸款,而貸款之前如果我們能夠審慎評估,並分析自己的還款能力之後在進行凍作,相信風險會小很多,因此就自己動動手來使用Google Sheet進行試算吧! 基本資料 ● 貸款總額: 1000000 ● 貸款期數: 84月 ● 年利率: 2.11% ● 月利率: 0.18% P.S 月利率 = 年利率 / 12 重要函式 PMT : 這是Google Sheet內建的重要年金計算公式,我們可以善用這個公式來計算固定利率及期數的固定攤還本息。因為PMT函式計算出的結果為負數,所以前面加上-號轉成正數。 動手做 首先我們在Excel表上列出我們的基本資料 圖片來源 其中月利率的部分就使用公式「=B4/12」 接著我們填上第一列的期數跟餘額 圖片來源 =B2 =B3 使用關鍵PMT函數來計算本息的部分 因為PMT函式計算出的結果為負數,所以前面加上-號轉成正數。 -PMT(貸款利率(月利率), 貸款期數, 貸款總額) =-PMT($B$5,$B$3,$B$2) 圖片來源 計算利息 利息 = 貸款餘額 x 月利率 =B8*$B$5 圖片來源 計算本金 本金 = 本息 - 利息 =C8-D8 圖片來源 製作第二列餘額的部分 餘額的部分 = 上一期的餘額 - 上一期的本金 圖片來源 接著拖曳該兩列往下拉,即可查看每一期的利息與本金 圖片來源 結語 雖然市面上已經有很多貸款銀行都提供了試算功能,但如果我們想要進一步管理自己的資產時,就需要將每一期的金額給計算出來,因此才會將公式運用在Excel表,讓我們的資產管理表能夠結合負債,進一步評估我們理財行動的下一步,希望這樣的經驗可以幫助到正在理財道路上打拼的夥伴,讓我們透過有效的管理,幫助荷包長大吧! 喜歡撰寫文章的你,不妨來了解一下: Web3.0時代下為創作者、閱讀者打造的專屬共贏平台 — 為什麼要加入? 歡迎加入一起練習寫作,賺取知識,累積財富!