node.js結(jié)合webSocket實現(xiàn)聊天室
全局安裝vue腳手架 npm install @vue/cli -g
創(chuàng)建 vue3 + ts 腳手架 vue create vue3-chatroom
后端代碼
src 同級目錄下建 server:

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server, { cors: true })
io.on('connection', (socket) => {
console.log('socket 已連接');
socket.on('sendToServer', data => {
console.log(`收到了前端發(fā)來的消息: ${data}`);
io.emit("sendToClient", data);
})
socket.on('disconnect', () => {
console.log('斷開連接');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});前端代碼
核心代碼:
import io from 'socket.io-client'
var socket = io('ws://localhost:3000')
socket.on("sendToClient", data => {
console.log(`收到了后端發(fā)來的數(shù)據(jù):${data}`);
records.value.push(JSON.parse(data))
})
const sendMessage = () => {
if (!message.value.trim()) return
const record: IRecord = reactive({
message: message.value,
nickname,
userId: new Date().getTime() + '',
color: '',
sendTime: getYMDHMS(new Date().getTime())
})
socket.emit('sendToServer', JSON.stringify(record));
message.value = '';
}完整代碼:
<template>
<div class="chat-room">
<div class="nav"></div>
<div class="main">
<div class="title">
<span>圖靈聊天室({{ userCount }})</span>
</div>
<div class="content" ref="recordsContent">
<div v-for="(itm, inx) in records" :key="inx">
<div
class="item"
:class="[itm.nickname === nickname ? 'item' : 'item-other']"
>
<div class="info">[ {{ itm.nickname }}:{{ itm.sendTime }} ]</div>
<span class="message">{{ itm.message }}</span>
</div>
</div>
</div>
<div class="input-box">
<div class="text">
<textarea :rows="8" v-model="message" @keydown="onKeydown"></textarea>
</div>
<div class="opt">
<button ghost @click="sendMessage">發(fā) 送</button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import io from 'socket.io-client'
import { reactive, ref } from 'vue'
interface IRecord {
nickname: string,
userId: string,
color: string,
message: string,
sendTime: string
}
const userCount = ref(2)
const records = ref<IRecord[]>([])
const message = ref('')
const nickname = localStorage.getItem('username') || '匿名用戶'
var socket = io('ws://localhost:3000')
socket.on("sendToClient", data => {
console.log(`收到了后端發(fā)來的數(shù)據(jù):${data}`);
records.value.push(JSON.parse(data))
})
const sendMessage = () => {
if (!message.value.trim()) return
const record: IRecord = reactive({
message: message.value,
nickname,
userId: new Date().getTime() + '',
color: '',
sendTime: getYMDHMS(new Date().getTime())
})
socket.emit('sendToServer', JSON.stringify(record));
message.value = '';
}
const onKeydown = (event: any) => {
if (event.keyCode === 13) {
sendMessage()
}
}
function getYMDHMS(timestamp:number) {
let time = new Date(timestamp)
let year = time.getFullYear()
let month:any = time.getMonth() + 1
let date:any = time.getDate()
let hours:any = time.getHours()
let minute:any = time.getMinutes()
let second:any = time.getSeconds()
if (month < 10) { month = '0' + month }
if (date < 10) { date = '0' + date }
if (hours < 10) { hours = '0' + hours }
if (minute < 10) { minute = '0' + minute }
if (second < 10) { second = '0' + second }
return year + '-' + month + '-' + date + ' ' + hours + ':' + minute + ':' + second
}
</script>
<style scoped lang="scss">
.chat-room {
margin: 0px auto;
width: 100%;
height: 100vh;
display: flex;
flex-direction: row;
border: 1px solid #ccc;
overflow: hidden;
.nav {
width: 66px;
background: #363636;
flex-shrink: 0;
}
.main {
display: flex;
background: #efefef;
flex: 1;
width: 0;
display: flex;
flex-direction: column;
.title {
height: 60px;
display: flex;
align-items: center;
font-size: 16px;
font-weight: 700;
padding-left: 20px;
border-bottom: 1px solid #c3c3c3;
flex-shrink: 0;
}
.content {
flex: 1;
height: 0px;
position: relative;
overflow-y: auto;
padding: 10px;
.item {
text-align: right;
.info {
font-size: 14px;
color: #666;
}
.message {
font-size: 18px;
background-color: rgba(110, 89, 228, 0.579);
margin: 10px;
padding: 8px 12px;
border-radius: 8px;
display: inline-block;
color: #333;
}
}
.item-other {
text-align: left;
.message {
background-color: rgb(218, 197, 112);
}
}
}
.input-box {
height: 230px;
border-top: 1px solid #c3c3c3;
flex-shrink: 0;
display: flex;
flex-direction: column;
.text {
flex: 1;
textarea {
width: 94%;
height: 160px;
font-size: 16px;
resize: none;
border: none;
padding: 8px 24px;
background: #efefef;
&:focus {
outline: none;
}
&:focus-visible {
outline: none;
}
}
}
.opt {
height: 60px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 20px;
}
}
}
}
</style>到此這篇關(guān)于node.js結(jié)合webSocket實現(xiàn)聊天室 的文章就介紹到這了,更多相關(guān)node.js webSocket聊天室 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
nodejs使用Sequelize框架操作數(shù)據(jù)庫的實現(xiàn)
這篇文章主要介紹了nodejs使用Sequelize框架操作數(shù)據(jù)庫的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
從零開始學(xué)習(xí)Node.js系列教程之基于connect和express框架的多頁面實現(xiàn)數(shù)學(xué)運算示例
這篇文章主要介紹了Node.js基于connect和express框架的多頁面實現(xiàn)數(shù)學(xué)運算,簡單講述了connect和express框架的原理及數(shù)學(xué)運算相關(guān)操作技巧,需要的朋友可以參考下2017-04-04
win系統(tǒng)下nodejs環(huán)境安裝配置
這篇文章主要介紹了win系統(tǒng)下nodejs環(huán)境安裝配置的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
使用nodejs?spider爬取圖片及數(shù)據(jù)實現(xiàn)
這篇文章主要為大家介紹了使用nodejs?spider爬取圖片及數(shù)據(jù)實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
windows如何把已安裝的nodejs高版本降級為低版本(圖文教程)
這篇文章主要介紹了windows如何把已安裝的nodejs高版本降級為低版本,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
node.js中的http.response.removeHeader方法使用說明
這篇文章主要介紹了node.js中的http.response.removeHeader方法使用說明,本文介紹了http.response.removeHeader的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下2014-12-12

