Node.js 與 Socket.io – 即時聊天室實作

許久沒有寫文章了(你好像常這樣說欸!),今天要來稍微講講專門用來實作即時通訊的 Node.js 模組 – Socket.io。

Socket.io 其實是一個完整實作 Websocket 的函式庫,他提供更簡單的方式讓開發者可以方便的使用 Websocket 這樣的通訊技術來實作許多應用。

我將以實作一個簡易聊天室作為範例來介紹這一個模組。

開始之前

這篇文章的程式範例將以 Node.js + Socket.io 為主,因此你必須先安裝好 Node.js 的環境,安裝方式請直接至官方網站下載安裝即可。

確認裝好 Node.js 的環境後,我們要來做一些基礎設定以及安裝該有的基本模組啦!請在你想要開發的資料夾中開啟終端機,輸入以下指令:

這兩行指令,第一行是在資料夾中產生一個 package.json 的檔案,這個檔案會紀錄專案的各種資訊,包含所相依的模組等等。

第二行指令則是安裝我們所需的兩種模組:Express.jssocket.io

接下來,我們在專案資料夾中開一個新檔案:index.js

一切就緒後,我們就可以開始進行了。

伺服器程式

HTTP

凡與 HTTP 有關係的東西就離不開 HTTP 伺服器啦!在 Node.js 中,建一個 HTTP 的伺服器非常簡單,大概就這不到 10 行的程式碼就能完成了吧。那個,別發呆,還不趕快把下面這幾行程式碼輸入到index.js中!

然後輸入這個指令來啟動伺服器:

你應該會看到終端機顯示這樣的字樣:

好了,你可以打開瀏覽器,然後輸入這個網址:http://localhost:3000

你的瀏覽器應該會出現

HTTP 伺服器完成!

Socket.io

再來是Socket.io的部分,這邊我們要稍微修改一下index.js的程式碼。

啟動方式跟我們在執行HTTP伺服器時一樣

然後你會發現什麼都沒有變

是的,因為我們的網站頁面還沒有放上去,當然什麼都不會變啊!畢竟這時候瀏覽器也不知道要打開Websocket呢!不信?那你連看看http://localhost:3000,看伺服器有沒有出現Hello啊!沒有對吧~

所以呢,接下來我們要透過網頁來與伺服器搭上線,抓緊,我們要準備起飛了。

網頁

伺服器大致完成後,要來處理人看得到的部分,也就是網頁呈現的部分。總不能只顯示個 Hello, World!,然後什麼事都不能做吧!?這樣還要聊個毛天啊!

所以,接下來請在你的專案資料夾下建立一個資料夾,這個資料夾專門用來存放網頁程式用,我想我們就叫做…views好了。

然後在views中建一個檔案:index.html。

這個檔案將會呈現我們聊天室的主要畫面,請記得在檔案裝輸入下方的程式碼。

然後修改index.js

這樣伺服器才會把我們剛剛的網頁內容推到瀏覽器上顯示。

那麼,這其實只是一個非常基本的頁面,只有一個目標,就是讓客戶端與伺服器的 WebSocket 連接埠建立連線。要確認有無連線,請重新整理剛剛打開的瀏覽器畫面,然後按下重新整理,你應該會在終端機中看到Hello!:關閉網頁的話會看到Bye~喔。

如果沒的話,重新執行一次伺服器吧,請記得先用CTRL+C關閉伺服器再啟動。

收發測試

現在我們要來做一點實驗,我們先在index.htmlbody部分加入如下的片段

喔對,還有修改伺服器的程式

重新啟動伺服器然後重新整理網頁,你應該會看到網頁上顯示Hi! Client.,這代表一切正常沒有問題。

在這一部份中,我們重新調整了伺服器的程式,以及前端網頁的JavaScript程式。

在前端網頁的部分

  • 更改body的內容,加入一個div來顯示接收到的訊息
  • 加入新的 JavaScript 程式,觸發伺服器回傳訊息與接收訊息並用div顯示

在伺服器的部分

  • 接收前端網頁的事件
  • 回傳一個附帶內容的事件給前端網頁

介面設計

秉持著自己的玩具自己做的精神,本教學不使用過多額外的框架,避免過於複雜的學習難度,所以在這邊你會看到許多原生的語法以及有點糟糕的程式碼

喔對,如果要說框架的話,我有用到一個:Vanilla.js

回到正題。

一個正常的聊天室,我們需要幾個基本功能:

  • 伺服器狀態
  • 發言者名稱
  • 顯示聊天內容
    • 發言者
    • 發言時間
    • 訊息內容
  • 訊息輸入

所以我們的介面大概會長這樣…等等你就會看到了。

好,開始囉。

index.html

之前加入

<body>...</body>替換成

重新整理網頁後應會看到一個新的畫面,這時還沒有任何功能,雖然有點簡陋,不過該有的都有啦,別嫌 XD。

接下來我們要來修改伺服器的部分,順便讓伺服器狀態這個功能動起來。

index.js

重啟伺服器與網頁,注意右上角的資訊,理應會看到:

這樣的資訊才對,如果沒有,那應該是失敗了,請再做一次看看。

這時你可以再開一個網頁視窗,應該會看到右上角的數字變成 2。

Node.js 與 Socket.io - 即時聊天室實作

訊息輸入

搞定了簡單的外觀後,接下來是訊息輸入的部分,也就是聊天內容輸入。

index.html

index.js

現在重新啟動伺服器和網頁,然後嘗試輸入一些東西後送出,觀察終端機的變化吧~

這裡我們在前端網頁的部分加入

  • 表單送出(submit)事件監聽器
    • 取消原有的送出動作
    • 讀取表單內容
    • 透過 socket 送出表單內容到伺服器

伺服器

  • 增加新的事件監聽器
    • 接收來自網頁端的訊息
    • 將訊息寫是在終端機上

顯示聊天訊息

完成了送出的部分,並且也確認伺服器能正確收到資料後,我們要來讓聊天室可以顯示這些聊天資料啦!

index.html

index.js

好,現在重啟伺服器,開兩個視窗,連上伺服器,你可以開始聊天了!(雖然是跟自己)

空白輸入

我想你有發現到,當你沒有輸入任何東西直接送出時還是能送出,這其實是一件很詭異的事情,所以我們要來解決這個問題。

index.html

  1. CSS 部分加入

  1. 替換掉原本的submit監聽器。

這樣前端網頁發現值為空時,除了警告提示外,也不會將事件送出去給伺服器。但這樣還不夠,如果有人直接對 WebSocket 送事件的話還是會被發現,所以我們要讓後端也能做一次驗證.

index.js

伺服器端的驗證很簡單,只判斷鍵值長度是否小於2,而2這個長度則是因為我們的訊息內寫包含有兩個東西

  1. 暱稱
  2. 訊息本體

好了,你可以嘗試把index.html中的if(ok)拿掉,然後試著不輸入任何東西直接送出,我相信伺服器他絕對是毫無反應,就只是個收到了,這樣。

結束之後

Demo

如果你有點懶得動手做,這邊有實品展示可以玩玩。

下一階

這個聊天室加入全新的功能,有興趣的話可以到這邊來看看:http://single9.net/2018/01/node-js-與-socket-io-即時聊天室實作二/

完整程式

感謝你看完這篇文章,如果你也有跟著時實做完文章內容,你應該會看到這樣的完整程式碼:

index.html

index.js

最後

這篇文章重點:

  • Node.js 專案初始化
  • Node.js HTTP 伺服器
  • Socket.io 應用
  • 全端技能++

感謝收看,我們下一篇再見~

在〈Node.js 與 Socket.io – 即時聊天室實作〉中有 6 則留言

  1. 多謝你的網誌,讓我更了解如何應用
    感謝

  2. 跟著你的文章順利做出來了~文章寫的很詳細易懂
    非常謝謝你

  3. 剛剛留言,結果卻沒出現? 不知道是什麼問題,總之謝謝你們這篇文章。

    但我又回頭留言主要的原因是 .. 我留言之後,重新連到這篇文章時
    原本程式碼片段的是像 gist 那樣有帶顏色的。
    但被轉址後網址多了 /amp/ ,程式碼片段就變成純文字了 …
    可是文章中有些連結又不會轉址,覺得怪怪的反應一下~
    還是有顏色比較容易閱讀啦 XD

    1. 最近比較忙沒什麼上來除草,感謝您的留言~

      沒跑出來原因是因為您是第一次留言,所以需要人工審核…XD

  4. 想請問 怎麼cordova 包裝成一個手機APP

您的見解

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料