Node.js+express+socket實現線上實時多人聊天室
阿新 • • 發佈:2021-07-13
本文例項為大家分享了Node.+express+socket實現線上實時多人聊天室的具體程式碼,供大家參考,具體內容如下
檔案結構如下:
前端部分:
登入頁面Login部分:
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>login</title> <link rel="stylesheet" href="/login.css" > </head> <body> <div class="login-box flex-box"> http://www.cppcns.com<!--登入標題欄--> <h2 class="sign-title box-width">LOGIN</h2> <!--頭像欄--> <div class="picture-carousel"> <div class="arrow left-arrow"> <div class="before-arrow"></div> </div> <img class="p1 img-setting" src="./img/1.jpg" alt="1.jpg"> <img class="p2 img-setting" src="./img/2.jpg" alt="2.jpg"> <img class="p3 img-setting" src="./img/3.jpg" alt="3.jpg"> <img class="p2 img-setting" src="./img/4.jpg" alt="4.jpg"> <img class="p1 img-setting" src="./img/5.jpg" alt="5.jpg"> <div class="arrow right-arrow"> <div class="after-arrow"></div> </div> </div> <!--使用者名稱欄--> <div class="name-box box-width"> <input type="text" class="user-name box-width" placeholder="Please Type Your Name"> </div> <!--確認欄--> <div class="button-box box-width"> <input type="button" class="login-button box-width" value="Login The Chatroom"> </div> <!--錯誤資訊欄--> <div class="error-box box-width"> <span class="error-message">Welcome to chatroom!</span> </div> </div> </body> <script src="js/login.js"></script> </html>
login.css
* { padding: 0; margin: 0; font-family: "Microsoft Yahei"; } html,body { width: 100%; height: 100%; font-family: "Microsoft Yahei"; display: flex; justify-content: center; align-items: center; } body { background: linear-gradient(-135deg,#51D15B,#42A855); background: -moz-linear-gradient(-135deg,#42A855); background: -webkit-linear-gradient(-135deg,#42A855); background: -o-linear-gradient(-135deg,#42A855); } .flex-box { display: flex; justify-content: center; align-items: center; } .box-width { width: 80%; } /*最外層*/ .login-box { width: 20%; min-width: 304px; max-width: 404px; height: 50%; min-height: 368px; max-height: 468px; flex-direction: column; box-shadow: 1px 1px 15px #7B8C99; background: #fff; } /*LOGIN標題*/ .sign-title { color: #42A855; border: 2px solid #42A855; border-top: transparent; border-left: transparent; border-right: transparent; } /*圖片切換*/ .picture-carousel { position: relative; display: flex; margin: 10%; } /*圖片切換箭頭*/ .arrow { z-index: 3; position: absolute; font-size: 60px; height: 100%; width: 30%; display: flex; justify-content: center; align-items: center; color: #ffffff; } .arrow:hover { cursor: pointer; } .left-arrow { left: 0; } .before-arrow { width: 0px; height: 0px; border-width: 30px; border-style: solid; border-color: transparent #51D15B transparent transparent; } .right-arrow { right: 0; } .after-arrow{ width: 0px; height: 0px; border-width: 30px; border-style: solid; border-color: transparent transparent transparent #51D15B; } .picture-carousel img { width: 80px; height: 80px; transition: all 0.2s linear; -moz-transition: all 0.2s ease-out; -webkit-transition: all 0.2s ease-out; -o-transition: all 0.2s ease-out; } .img-setting { margin: 0px -15px; } .p1 { transform: scale(0.6); z-index: 1; } .p1:hover { transform: scale(0.8); } .p2 { transform: scale(0.8); z-index: 2; } .p2:hover { transform: scale(1); } .p3 { transform: scale(1); z-index: 3; } .p3:hover { transform: scale(1.2); } /*使用者名稱*/ .name-box { display: flex; justify-content: center; border: 1px solid #51D15B; } .name-box .user-name { width: 100%; text-align: center; padding: 10px; outline-color: #42A855; border: none; font-size: 16px; } /* 登入按鈕 */ .button-box{ display: flex; justify-content: center; margin: 10px 0 20px; } .button-box .login-button{ width: 100%; padding: 10px 20px; outline:none; border: none; background: #42A855; color: white; font-size: 16px; } /* 錯誤資訊 */ .error-box{ color: #42A855; border: 2px solid #42A855; border-top: transparent; border-left: transparent; border-right: transparent; } .error-box span{ visibility: hidden; color: #d43f3a; font-size: 14px; }
login.js
// 用於儲存圖片順序 var imgArray = ['1','2','3','4','5']; // 獲取箭頭 var leftArrow = document.getElementsByClassName('left-arrow')[0]; var rightArrow = document.getElementsByClassName('right-arrow')[0]; // 獲取使用者名稱 var userName = document.getElementsByClassName('user-name')[0]; // 獲取登入按鈕 var loginButton = document.getElementsByClassName('login-button')[0]; // 獲取錯誤資訊欄 var errorMessage = document.getElementsByClassName('error-message')[0]; // 新增左箭頭監聽事件 leftArrow.addEventListener('click',function(){ imgArray.unshift(imgArray[imgArray.length - 1]); // 向陣列的開頭新增一個元素 // imgArray.pop(); // 刪除並返回陣列的最後一個元素 carouselImg(); // 切換圖片 }); // 新增右箭頭監聽事件 rightArrow.addEventListener('click',function(){ imgArray.push(imgArray[0]); // 把第一個元素放在最後 imgArray.shift(); // 刪除並返回陣列的第一個元素 carouselImg(); // 切換圖片 }); // 切換圖片 function carouselImg(){ for(var count = 0;count < imgArray.length;count++){ document.getElementsByTagName('img')[count].src = './img/' + imgArray[count] + '.jpg'; document.getElementsByTagName('img')[count].alt=imgArray[count] + '.jpg'; } } // 新增登入按鈕監聽事件 loginButton.addEventListener('click',function(){ if(userName.value === ''){ errorMessage.innerHTML = 'Please Type You Name'; errorMessage.style.visibility = 'visible'; }else if(userName.value.length > 8){ errorMessage.innerHTML = 'Your Name Cannot Over 8 Words'; errorMessage.style.visibility = 'visible'; }else{ window.location.href=encodeURI('index.html?selectpicture=' + document.getElementsByClassName('p3')[0].alt + '&username=' + userName.value); } }); // Enter按鍵繫結登入事件 document.onkeydown = function (event) { var e = event || window.event; if(e && e.keyCode === 13){ loginButton.click(); } };
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>chat-room</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="./css/index.css" /> </head> <body> <div class="chat-box"> <!-- 聊天框頭部 --> <div class="chat-header"> <div class="button-box"> <input type="button" class="log-out" value="LOGOUT" /> </div> </div> <!-- 聊天框主體 --> <div class="chat-body"> <!-- 聊天框左側 --> <div class="chat-body-left"> <!-- 聊天框左側聊天內容 --> <div class="chat-content"></div> <!-- 聊天框左側聊天輸入框 --> <div class="chat-edit"> <input type="text" class="edit-box" placeholder="Please Type You Message" maxlength="15"/> <input type="button" class="edit-button" value="SEND" /> </div> </div> <!-- 聊天框右側 --> <div class="chat-body-right"> <!-- 聊天框右側統計人數 --> <div class="online-count">Online:0</div> <!-- 聊天框右側使用者名稱 --> <div class="user-name">user-name</div> <!-- 聊天框右側頭像 --> <img class="user-img" /> </div> </div> </div> </body> </html> <script src="./js/socket.io.js"></script> <script src="./js/index.js"></script>
index.css
*{
margin: 0;
padding: 0;
font-family: "Microsoft Yahei"
}
html,body{
width: 100%;
height: 100%;
}
/* 背景色 */
body{
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(-135deg,#42A855);
background: -moz-linear-gradient(-135deg,#42A855);
background: -webkit-linear-gradient(-135deg,#42A855);
background: -o-linear-gradient(-135deg,#42A855);
}
/* 最外層 */
.chat-box{
width: 50%;
max-width: 720px;
min-width: 400px;
height: 80%;
min-height: 530px;
max-height: 530px;
display: flex;
flex-direction: column;
background: #fff;
box-shadow: 1px 1px 15px #333;
}
/* 頭部 */
.chat-header{
margin: 5px;
box-shadow: 1px 1px 15px #7B8C99;
}
.button-box{
display: flex;
justify-content: flex-end;
}
.log-out{
height: 100%;
font-size: 14px;
font-weight: bold;
padding: 5px 15px;
color: #79C2EA;
background: #fff;
outline: none;
border: none;
border-radius: 15px;
cursor: pointer;
}
/* 主體 */
.chat-body{
height: 90%;
display: flex;
flex-directioAOXIuCdYSn: row;
justify-content: space-around;
align-items: center;
margin: 5px;
padding: 5px;
}
/* 主體左側 */
.chat-body-left{
height: 100%;
width: 70%;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 5px;
}
/* 左側內容 */
.chat-content{
box-shadow: 1px 1px 15px #7B8C99;
height: 100%;
margin-bottom: 5px;
overflow: scroll;
}
/*聊天氣泡*/
.my-message-box {
display: flex;
justify-content: flex-end;
align-content: center;
margin: 5px;
}
.other-message-box {
display: flex;
justify-content: flex-start;
align-content: center;
margin: 5px;
}
.message-content {
display: flex;
justify-content: center;
align-content: center;
background-color: #51D15B;
padding:5px 10px;
border-radius: 15px;
color: #fff;
}
.other-message-content{
display: flex;
justify-content: center;
align-content: center;
background-color: #79C2EA;
padding: 5px 10px;
border-radius: 15px;
color: #fff;
}
.message-content span{
padding:20px 0px;
}
.user-chat-img {
width: 50px;
height: 50px;
}
.other-message-content span{
padding: 20px 0px;
}
.message-arrow{
width: 0;
height: 0;
border-width:8px;
border-style: solid;
border-color: transparent transparent transparent #51D15B;
align-self: center;
}
.other-message-arrow{
width: 0;
height: 0;
border-width: 8px;
border-style: solid;
border-color: transparent #79C2EA transparent transparent;
align-self: center;
}
.user-information{
display: flex;
flex-direction: column;
align-content: flex-end;
}
.other-user-information{
display: flex;
flex-direction: column;
align-content: flex-end;
}
.user-chat-name{
color: #333;
font-size: 16px;
text-align: center;
}
/* 聊天輸入框 */
.chat-edit{
margin-top: 5px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 1px 1px 15px #7B8C99;
overflow: hidden;
}
/* 聊天輸入框輸入區域 */
.edit-box{
width: 80%;
height: 100%;
margin: 5px;
border: none;
outline: none;
}
/* 聊天輸入框按鈕 */
.edit-button{
height: 100%;
padding: 5px 15px;
background: #fff;
color: #79C2EA;
outline: none;
border: none;
border-radius: 15px;
cursor: pointer;
font-size: 14px;
font-weight: bold;
}
/* 主體右側 */
.chat-body-right{
height: 100%;
width: 30%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 5px;
box-shadow: 1px 1px 15px #7B8C99;
}
.user-name{
margin: 15px;
font-size: 18px;
font-weight: bold;
color: #79C2EA;
}
.user-img{
width: 100px;
height: 100px;
margin: 5px;
}
.online-count{
font-size: 18px;
font-weight: bold;
color: #79C2EA;
}
/* 相容小螢幕 */
@media screen and (max-width:420px){
.chat-box{
width: 50%;
max-width: 720px;
min-width: 300px;
height: 80%;
min-height: 530px;
max-height: 530px;
}
.chat-body-left{
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 5px;
}
.chat-body-right{
display: none;
}
}
index.js
// 獲取url裡面的內容 var url = decodeURI(location.href).split('?')[1].split('&'); //..陣列第一個元素為圖片路徑,第二個元素為使用者名稱 console.log(url); // 獲取聊天內容框 var chatContent = document.getElementsByClassName('chat-content')[0]; // 獲取聊天輸入框 var editBox = document.getElementsByClassName('edit-box')[0]; // 獲取聊天輸入框傳送按鈕 var editButton = document.getElementsByClassName('edit-button')[0]; // 獲取使用者名稱欄 var userName = document.getElementsByClassName('user-name')[0]; // 獲取線上人數欄 var onlineCount = document.getElementsByClassName('online-count')[0]; // 登入頁面的名稱放在右側 userName.innerHTML = url[1].split('=')[1]; var userImg = document.getElementsByClassName('user-img')[0]; // 把登入頁面的頭像放在右側 userImg.src = `./img/${url[0].split('=')[1]}`; var logOut = document.getElementsByClassName('log-out')[0]; // 傳送按鈕繫結點選事件 editButton.addEventListener('click',sendMessage); // 登出按鈕繫結點選事件 logOut.addEventListener('click',closePage); // 繫結Enter鍵和傳送事件 document.onkeydown = function(event){ var e = event || window.event; if(e && e.keyCode === 13){ if(editBox.value !== ''){ editButton.click(); } } }; // 關閉頁面 function closePage(){ var userAgent = navigator.userAgent; console.log(`userAgent=${userAgent}`); if(userAgent.indexOf('Firefox') != -1 || userAgent.indexOf("Chrome") != -1){ //..如果是火狐或者谷歌 window.location.href = "about:blank"; }else{ window.opener = null; window.open("","_self"); window.close(); } } // socket部分 var socket = io(); // 當接收到訊息並且不是本機時生成聊天氣泡 socket.on('message',function(information){ console.log('收到訊息',information); if(information.name !== userName.textContent){ // 不是本機時 createOtherMessage(information); // 生成聊天氣泡 } }); // 當接收到有人連線進來 socket.on('connected',function(onlinecount){ console.log(`有人登入,線上人數為:${onlinecount}`); onlineCount.innerHTML = 'Online:' + onlinecount; }); // 當接收到有人斷開後 socket.on('disconnected',function(onlinecount){ console.log(`有人www.cppcns.com斷開啦:當前人數為:${onlinecount}`); onlineCount.innerHTML = 'Online:' +onlinecount; }); // 傳送本機的訊息 function sendMessage(){ if(editBox.value != ''){ //..如果傳送內容不為空 var myInformation = { name :userName.textContent,chatContent : editBox.value,img : userImg.src }; socket.emit('message',myInformation); createMyMessage(); // 建立本機聊天氣泡 editBox.value = ''; //..清空文字框 } } // 生成本機的聊天氣泡 function createMyMessage(){ var myMessageBox = document.createElement('div'); myMessageBox.className = 'my-message-box'; var messageContent = document.createElement('div'); messageContent.className = 'message-content'; var text = document.createElement('span'); text.innerHTML = editBox.value; messageContent.appendChild(text); myMessageBox.appendChild(messageContent); var arrow = document.createElement('div'); arrow.className = 'message-arrow'; myMessageBox.appendChild(arrow); var userInformation = document.createElement('div'); userInformation.className = 'user-information'; var userChatImg = document.createElement('img'); userChatImg.className = 'user-chat-img'; userChatImg.src = userImg.src; var userChatName = document.createElement('div'); userChatName.className = 'user-chat-name'; userChatName.innerHTML= userName.textContent; userInformation.appendChild(userChatImg); userInformation.appendChild(userChatName); myMessageBox.appendChild(userInformation); chatContent.appendChild(myMessageBox); chatContent.scrollTop = chatContent.scrollHeight; // 滾動到最新聊天內容 } // 生成其他使用者的聊天氣泡 function createOtherMessage(information) { var otherMessageBox = document.createElement('div'); otherMessageBox.className = 'other-message-box'; var otherUserInformation = document.createElement('div'); otherUserInformation.className = 'other-user-information'; var userChatImg = document.createElement('img'); userChatImg.className = 'user-chat-img'; userChatImg.src = information.img; var userChatName = document.createElement('span'); userChatName.className = 'user-chat-name'; userChatName.innerHTML = information.name; otherUserInformation.appendChild(userChatImg); otherUserInformation.appendChild(userChatName); otherMessageBox.appendChild(otherUserInformation); var otherMessageArrow = document.createElement('div'); otherMessageArrow.className = 'other-message-arrow'; otherMessageBox.appendChild(otherMessageArrow); var otherMessageContent = document.createElement('div'); otherMessageContent.className = 'other-message-content'; var text = document.createElement('span'); text.innerHTML = information.chatContent; otherMessageContent.appendChild(text); otherMessageBox.appendChild(otherMessageContent); chatContent.appendChild(otherMessageBox); chatConthttp://www.cppcns.coment.scrollTop = chatContent.scrollHeight; }
server.js
// 引入必須模稜 var express = require('express'); var app = express(); var http = require('http').Server(app); var io = require('socket.io')(http); var path = require('path'); // 線上人數統計 var onlineCount = 0; app.use(express.static(__dirname)); // 路徑對映 app.get('/login.html',function(request,response){ response.sendFile('login.html'); }); // 當有使用者連線進來時 io.on('connection',function(socket){ console.log('a user connected'); // 傳送給客戶端線上人數 io.emit('connected',++onlineCount); // 當有使用者斷開 socket.on('disconnect',function(){ console.log('user disconnected'); // 傳送給客戶端人數 io.emit('disconnected',--onlineCount); console.log(onlineCount); }); // 收到了客戶端發來的訊息 socket.on('message',function(message){ // 給客戶端傳送訊息 console.log('伺服器收到的訊息為:',message); io.emit('message',message); }); }); var server = http.listen(4000,function(){ console.log('Server is running'); });
最後
終端輸入
node server.js
瀏覽器位址列輸入
http://localhost:4000/login.html
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。