iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Software Development

新手也能打造網路電話系統-WebRTC入門與活用系列 第 12

Day 12 - 應用篇 - 建構WebSocket聊天室(Client端)

上一篇介紹了WebSocket聊天室系統的整體架構,本篇我們要打造系統的Client端。

Client端有以下的功能:

  • 提供輸入視窗讓使用者輸入名稱。
  • 連線至Socket Server進行即時通訊。
  • 成員加入與離開聊天室時顯示通知。
  • 聊天室訊息發送與顯示。
  • 收到新訊息時滾動置底。

本文延續Day11的專案架構,因此請先閱讀並完成Day11的內容。

專案開發

介面設計

首先,開啟index.html檔案,並撰寫以下程式碼。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0, minimum-scale=1, maximum-scale=1">
    <title>Day12-13</title>
    <!-- 匯入CSS檔案 -->
    <link rel="stylesheet" type="text/css" href="main.css">
</head>

<body>
    <!-- 建立h3標題 -->
    <h3 id="title">歡迎來到WebSocket聊天室</h3>
    <!-- 建立ul清單,用於顯示聊天室訊息 -->
    <ul id="messages"></ul>
    <!-- 建立form表單,內部包含input元件及button元件 -->
    <form id="form" action="">
        <input id="input" autocomplete="off">
        <button>Send</button>
    </form>
    <!-- 匯入Socket.IO套件 -->
    <script src="/socket.io/socket.io.js"></script>
    <!-- 匯入JavaScript程式碼 -->
    <script src="index.js"></script>
</body>

</html>

接著,開啟main.css檔案,並撰寫以下程式碼。

body {
    background: #F3E8EB;
    margin: 0;
    padding-bottom: 3rem;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

#title {
    display: flex;
    justify-content: center;
}

#form {
    background: #C2B4D6;
    padding: 0.25rem;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    height: 3rem;
    box-sizing: border-box;
    backdrop-filter: blur(10px);
}

#input {
    border: none;
    padding: 0 1rem;
    flex-grow: 1;
    border-radius: 2rem;
    margin: 0.25rem;
}

#input:focus {
    outline: none;
}

#form>button {
    background: #57648C;
    border: none;
    padding: 0 1rem;
    margin: 0.25rem;
    border-radius: 3px;
    outline: none;
    color: #fff;
}

#messages {
    list-style-type: none;
    margin: 0;
    padding: 0;
}

#messages>li {
    padding: 0.5rem 1rem;
}

#messages>li:nth-child(odd) {
    background: #fae3d3;
}

程式設計

開啟index.js檔案,並撰寫以下程式碼。

let userName = ""; //用於儲存使用者名稱

//設定Socket連線的配置,配置內容為連線至本地端的port:3001,並關閉自動連線
const socket = io(
    'localhost:3001', { 'autoConnect': false }
);

function init() {
    //Step1:取得index.html中的元件
    const title = document.getElementById('title');
    const form = document.getElementById('form');
    const input = document.getElementById('input');

    //Step2:顯示輸入框讓使用者輸入名稱,並修改標題內容
    userName = prompt('請輸入你的名稱');
    if (!userName || userName == '') {
        title.textContent = '請重新載入網頁並輸入你的名稱';
        return;
    } else {
        title.textContent = `Hi, ${userName}, 歡迎來到WebSocket聊天室`;
    }

    //Step3:設定元件的監聽事件
    form.addEventListener('submit', function(e) {
        e.preventDefault();
        if (input.value && socket.connected) {
            socket.emit('message', userName, input.value); //發送message事件,以發送訊息
            input.value = ''; //清空輸入的訊息內容
        }
    });

    //Step4:設定Socket的監聽事件
    socket.on('connect', () => { //成功連線至Socket Server後,進入此監聽事件
        socket.emit('join', userName); //發送join事件,以加入聊天室
    });

    socket.on('new member', (name) => { //當有新成員加入聊天室後,進入此監聽事件
        showMsg(`【${name} 進入聊天室】`); //顯示新成員進入聊天室的訊息
    });

    socket.on('new message', (name, msg) => { //當有新訊息後,進入此監聽事件
        showMsg(`${name} 說:${msg}`); //顯示新訊息
    });

    socket.on('member leave', (name) => { //當有成員離開聊天室後,進入此監聽事件
        showMsg(`【${name} 離開聊天室】`); //顯示成員離開聊天室的訊息
    });

    //Step5:連線至Socket Server
    socket.connect();
}

function showMsg(text) {
    //建立用於顯示訊息的清單項目元件
    const item = document.createElement('li');
    item.textContent = text;
    //將清單項目元件呈現於訊息列表
    const messages = document.getElementById('messages');
    messages.appendChild(item);
    //滾動置底
    window.scrollTo(0, document.body.scrollHeight);
}

init();

在這段程式碼中,主要定義了兩個方法,init方法會在網頁呈現時執行,showMsg方法用於將訊息呈現於畫面,以下說明核心的init方法內做了哪些事情:

  • Step1:先取得index.html中定義的元件,並宣告成變數以利後續使用。
  • Step2:使用prompt方法來顯示輸入框,讓使用者輸入自己的聊天室名稱,並將名稱儲存於userName變數,接著判斷使用者是否有正確輸入名稱,若有則修改標題以歡迎使用者,若無則修改標題以提示使用者重新載入網頁並輸入名稱。
  • Step3:設定form表單元件的監聽事件,若按鈕被點擊,則向Server傳送輸入的訊息。
  • Step4:設定Socket的監聽事件,當收到Server傳送的事件時進行相應的處理。
  • Step5:執行socket的connect方法,以連線至Socket Server。

執行結果

程式碼撰寫完成後,我們可以用Chrome開啟index.html檔案,大家會看到以下的成品。由於Server還未啟動,所以不會有任何的功能,因此下一回要實作Server端的程式碼,將整個聊天室系統搭建起來。


上一篇
Day 11 - 應用篇 - 建構WebSocket聊天室(架構總覽)
下一篇
Day 13 - 應用篇 - 建構WebSocket聊天室(Server端)
系列文
新手也能打造網路電話系統-WebRTC入門與活用30

尚未有邦友留言

立即登入留言