Let’s build a simple chatroom by Node.js(1)

Gordon Fang
6 min readMar 10, 2019

--

即時應用程式發展簡史

過去網站是建立在「客戶端向伺服器要資料,伺服器盡可能地滿足客戶端的需求」這種架構模式,一直持續到2005年AJAX的出現,許多人開始在想有沒有可能能在客戶端與伺服器端建立一個雙向連線。

伴隨著網站技術的成長過程中,網站所要消耗的資料量日益龐大,傳統HTTP( HyperText Transfer Protocol,超文字傳輸協定)協定下的主從架構面臨最大的挑戰在於是否仍然能應付來自客戶端的海量請求,為了解決問題,不乏很多不同的推播技術,例如:長輪詢(long-polling)等, 輪詢(polling)方式為每隔一段時間詢問有沒有訊息需要更新,因為要不停地連接,所以HTTP至始至終都是打開來的,因此長久下來效率低、浪費資源、治標不治本。

每當你向伺服器發送出HTTP封包時,封包又夾雜了些標頭(header)和cookie,需要被傳送的資料特別大,變相地導致傳輸上的延遲,假設你正在網頁版的即時對戰遊戲,這時候「傳輸上的延遲」成了關鍵。

最主要的傳輸上的延遲是因為HTTP是最基本的網路協定,本身單向傳輸,客戶端向伺服器端先傳一個ACK封包,如果伺服器端有收到才回傳另一個ACK封包,代表伺服器端是有收到的,接著才開始建立連線,客戶端開始向伺服器丟封包。上述可知HTTP是單向、且半雙工,另外一點是HTTP協定視每一個連線是獨立的,不會記錄先前的連線紀錄,當客戶端的請求封包多時,HTTP該如何克服?

所以如何製作一個穩定、且低延遲的連線正是在Websocket所存在的必要性

淺談Websocket

websocket使得瀏覽器具備雙向溝通的功能,連線過程稱之為websocket handshake,一開始客戶端會先發送正常版的HTTP協定封包,其標頭會寫 Upgrade,告知伺服 端請求websocket連線,以下是HTTP協定範例標頭。

GET ws://websocket.example.com/ HTTP/1.1
Origin: http://example.com
Connection: Upgrade
Host: websocket.example.com
Upgrade: websocket

如果伺服端有支援websocket連線,那麼他回傳傳送封包包含以下範例標頭,並同意連線。

HTTP/1.1 101 WebSocket Protocol Handshake
Date: SAT, 09 MAR 2019 18:51:50 GMT
Connection: Upgrade
Upgrade: WebSocket

資料以訊息(message)方式經由websocket傳輸,每一個訊息包含了多個訊框(frame),為了確保每一個訊框送到客戶端時能夠順利地重新被組裝起來,每個訊框前4到12個位元組記錄著payload。我們要實作的聊天室所用的socket.io套件就是以web-socket為基底所完成的。

Node.js 實作

檔案部屬

下載套件

mime (Multipurpose Internet Mail Extensions, MIME type, 多用途網際網路郵件擴展) 套件,取得副檔名是MIME型態的檔案

socket.io套件在聊天室這個小專案用來主從溝通、推播到其他客戶端、事件處理。

伺服器配置(server.js)

導入模組
傳送檔案、錯誤處理
快取檔案流程圖
快取檔案

存取記憶(RAM)比存取檔案系統還快,這邊我們將聊天程式加入到快取,頭一次存取時,磁碟會去讀取它,下一次存取時,我們的程式會判斷是否曾經存取過,若有的我們就到快取撈取。

建立HTTP伺服器

到這邊HTTP伺服器架構差不多完成了,可以在終端打上node server.js,伺服器就開始執行,這時可以瀏覽器打上http://127.0.0.1:3000,觀看運作結果,結果會顯示404錯誤訊息,因為我們還沒建構index.html。

網頁配置(index.html)

網頁內容

上面我們有下載socket.io的套件,這邊我們的網頁需要掛上去,否則無法運作socket.io伺服器。

<script src='/socket.io/socket.io.js' type='text/javascript'></script>

啟用Socket.io伺服器

導入socket.io模組、宣告變數
暱稱處理
socket 事件發射器示意圖
加入聊天室處理
更名處理
廣播訊息處理、聊天室處理、離線處理
廣播訊息示意圖
匯出socket.io模組

下篇幅文章我們將講解socket.io其他事件處理、聊天室使用者介面Javascript配置。

--

--

Gordon Fang
Gordon Fang

Written by Gordon Fang

Hi 我是 Gordon,目前是自然語言實驗室的研究生,曾經是金融業軟體工程師,我對大語言模型、設計模式、Linux、平面設計都有涉略,歡迎相互交流。

No responses yet