原生JavaScript+WebSocket+nodejs實現聊天室功能
碼字不易,有幫助的同學希望能關注一下我的微信公眾號:Code程式人生,感謝!程式碼自用自取。
WebSocket也是前端非常重要的技術棧。
現在各種網站、App、小程式都伴有即時通訊的功能。WebSocket的主要應用就是即時通訊。
WebSocket的介紹在網上非常非常多,也非常詳細,我就不做過多介紹了。
WebSocket的出現解決了遠古時期http輪詢的”醜陋“。
我這期視訊使用原生JavaScript+nodejs實現一個最基本的聊天室功能。
我先介紹一個目錄檔案:
前端內容存放在chat資料夾中,一共兩個頁面,entry.html
前端部分:
entry.html內容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</ title>
</head>
<body>
<input type="text" id="username" placeholder="請輸入使用者名稱"/>
<button id="enter">進入聊天室</button>
<script>
;((doc,storage,location) => {
const oUsername = doc.querySelector ('#username');
const oEnterBtn = doc.querySelector('#enter');
const init = () => {
bindEvent();
}
function bindEvent(){
oEnterBtn.addEventListener('click',handleEnterBtnClick,false);
}
function handleEnterBtnClick(){
const username = oUsername.value.trim();
console.log(username);
if(username.length < 6){
alert('使用者名稱不能小於6位');
return;
}
storage.setItem('username',username);
location.href = 'index.html';
}
init();
})(document,localStorage,location);
</script>
</body>
</html>
這個頁面主要是做一個登入,做的有點粗糙,沒寫UI,主要還是為了存放一個localStorage用於下個頁面通訊。
index.html內容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="list">
<input type="text" id="message" placeholder="請輸入訊息" />
<button id="send">傳送</button>
</ul>
<script>
const oList = document.querySelector('#list');
const oMessage = document.querySelector('#message');
const oSendBtn = document.querySelector('#send');
let username = '';
const ws = new WebSocket('ws:localhost:8000');
oSendBtn.addEventListener('click',handleSendBtnClick,false);
ws.addEventListener('open',handleOpen,false);
ws.addEventListener('close',handleClose,false);
ws.addEventListener('error',handleError,false);
ws.addEventListener('message',handleMessage,false);
function handleSendBtnClick(){
console.log('send message');
const msg = oMessage.value;
if(!msg.trim().length){
return;
}
ws.send(JSON.stringify({
user:username,
dateTime:new Date().getTime(),
message:msg
}))
oMessage.value = '';
}
function handleOpen(){
console.log('WebSocket open');
username = localStorage.getItem('username');
if(!username){
location.href = 'entry.html';
return;
}
}
function handleClose(){
console.log('WebSocket close');
}
function handleError(){
console.log('WebSocket error');
}
function handleMessage(e){
console.log('WebSocket message');
console.log(e);
const msgData = JSON.parse(e.data);
oList.appendChild(createMsg(msgData));
}
function createMsg(data){
const {user,dateTime,message} = data;
const oItem = document.createElement('li');
oItem.innerHTML = `
<p>
<span>${user}</span>
<i>${new Date(dateTime)}</i>
</p>
<p>訊息:${message}</p>
`
return oItem;
}
</script>
</body>
</html>
這個頁面是聊天室的內容,伴隨了很多dom操作,可能有點亂,我也沒有分模組,全寫在一起了,方便複製貼上。
前端部分其實主要就是例項化了一個WebSocket物件,無論是前端還是後端,WebSocket都是一個以事件驅動的方式存在。
前端主要事件是open、close、error、message。
open、close、error的功能就和名字一樣,不做過多解釋。
主要是message事件,它主要是接收來自後端推送過來的資訊。
後端部分
後端在編寫之前要先安裝ws模組,開啟控制檯輸入
npm i ws -s
index.js
const ws = require('ws');
;((ws)=>{
const server = new ws.Server({port:8000});
const init = () => {
bindEvent();
}
function bindEvent() {
server.on('open',handleOpen);
server.on('close',handleClose);
server.on('error',handleError);
server.on('connection',handleConnection);
}
function handleOpen(){
console.log('WebSocket open');
}
function handleClose(){
console.log('WebSocket close');
}
function handleError(){
console.log('WebSocket error');
}
function handleConnection(ws){
console.log('WebSocket connection');
ws.on('message',handleMessage);
}
function handleMessage(msg){
console.log('WebSocket message');
console.log(msg);
server.clients.forEach(function(c){
c.send(msg);
})
}
init();
})(ws);
後端使用nodejs,也是採用事件驅動的方式執行。
主要事件有:open、close、error、message、connection
前三個事件還是形如其名。
message事件存放於connection事件的引數裡的,所以要在connection中繫結message事件。
connection就是代表通訊是否連線成功的事件。
message的引數就是前端傳過來的資訊。
然後要做的就是把接收到的前端資訊分發聊天室所有的人。
在程式碼的最頂部,我們例項化了一個ws模組的Server物件。
Server物件裡有一個clients屬性,所有登入在聊天室的人都掛載在這個clients屬性上。
所以我們只需要forEach迴圈把接收到的前端資訊分發給每一個人即可。
其實到現在為止我們就完成了一個最基本的基於WebSocket技術的原生JavaScript實現的聊天室。
我分別打開了一個chrome瀏覽器和uc瀏覽器。
我們看一下效果:
沒有任何問題,一個最基本的聊天室的內容已經搭建完成。
如果你想商用,或者參加一些比賽,可以美化一下UI,把一些細節操作優化一下。
可以直接複製文章中的程式碼,貼上使用,按照操作來,不會有任何問題。
如果想要原始碼檔案,關注我的公眾號回覆聊天室即可。
有微信小程式課設、畢設需求聯絡個人QQ:505417246
關注下面微信公眾號,可以領取微信小程式、Vue、TypeScript、前端、uni-app、全棧、Nodejs、Python等實戰學習資料
最新最全的前端知識總結和專案原始碼都會第一時間釋出到微信公眾號,請大家多多關注,謝謝!