1.前端逻辑
本项目基于之前搭建的vite环境:https://blog.csdn.net/beekim/article/details/128083106?spm=1001.2014.3001.5501
新增一个登录页和聊天室页面
<template>
<div>登录页</div>
<div>
用户名:<input type="text" placeholder="请输入用户名" v-model="username" /><br />
<button @click="enter">进入聊天室</button>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { useRouter } from "vue-router";
const username = ref();
const { replace } = useRouter();
onMounted(() => {
username.value = localStorage.getItem("_username");
if (username.value) {
replace({ path: "/chatRoom" });
}
});
const enter = () => {
const _username = username.value.trim();
if (_username.length > 0) {
localStorage.setItem("_username", _username);//缓存当前登录人
replace({ path: "/chatRoom" });
}
};
</script>
<style scoped lang="less"></style>
<template>
<div>聊天室</div>
<div class="msg-list" v-if="msgList">
<div v-for="(item, index) in msgList" :key="index">
<div>
<span>{{ item.user }}</span>
<span>{{ item.date }}</span>
</div>
<div>消息:{{ item.msg }}</div>
</div>
</div>
<div>
<input type="text" placeholder="请输入消息" v-model="msg" />
<button @click="send">发送</button>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
const msgList = ref<any>([]);
const msg = ref();
const send = () => {
if (!msg.value.trim().length) return;
msgList.value.push({
id: new Date().getTime(),
user: localStorage.getItem("_username"),
date: new Date(),
msg: msg.value,
});
};
</script>
<style scoped lang="less"></style>
2.封装websocket
const useWebSocket = (handleMessage: any) => {
const ws = new WebSocket('ws://localhost:8000');
const init = () => {
bindEvent();
};
function bindEvent() {
ws.addEventListener("open", handleOpen, false);
ws.addEventListener("close", handleClose, false);
ws.addEventListener("error", handleError, false);
ws.addEventListener("message", handleMessage, false);
}
function handleOpen(e) {
console.log("WebSocket open", e);
}
function handleClose(e) {
console.log("WebSocket open", e);
}
function handleError(e) {
console.log("WebSocket open", e);
}
init();
return ws;
};
export { useWebSocket };
3.后端(node)逻辑
先在根目录建一个server文件夹,在下面建一个index.js文件(node需要js文件才可以执行,别建ts文件),然后执行以下两条命令
npm init -y
yarn add ws
index.js
console.log("测试websocket");
const WebSocket = 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("webscoket open");
}
function handleClose() {
console.log("webscoket close");
}
function handleError() {
console.log("webscoket error");
}
function handleConnection(ws) {
console.log("webscoket connection");
ws.on("message", handleMsg);
}
function handleMsg(msg) {
console.log(JSON.parse(msg));
server.clients.forEach((c) => {
c.send(msg); //广播消息
});
}
init();
})(WebSocket);
4.测试
在测试之前需启动后台
执行node index.js
还需调整聊天室页面的代码为:
<template>
<div>聊天室</div>
<div class="msg-list" v-if="msgList">
<div v-for="(item, index) in msgList" :key="index">
<div>
<span>{{ item.user }}</span>
<span>{{ item.date }}</span>
</div>
<div>消息:{{ item.msg }}</div>
</div>
</div>
<div>
<input type="text" placeholder="请输入消息" v-model="msg" />
<button @click="send">发送</button>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useWebSocket } from "@/hooks/index";
const msgList = ref<any>([]);
const msg = ref();
// {
// id: new Date().getTime(),
// user:localStorage.getItem('_username'),
// date:new Date().getTime(),
// msg:'bbbbb'
// }
const handleMessage = (e) => {
console.log(e);
// const _msgData = JSON.parse(e.data);
// console.log(_msgData);
//因为从后台接收到的数据是blob类型的值,所以转换一下
e.data.text().then((v) => {
console.log(v);
msgList.value.push(JSON.parse(v));
});
// msgList.value.push(_msgData);
};
const ws = useWebSocket(handleMessage);
const send = () => {
if (!msg.value.trim().length) return;
// msgList.value.push({
// id: new Date().getTime(),
// user: localStorage.getItem("_username"),
// date: new Date(),
// msg: msg.value,
// });
ws.send(
JSON.stringify({
id: new Date().getTime(),
user: localStorage.getItem("_username"),
date: new Date(),
msg: msg.value,
})
);
};
</script>
<style scoped lang="less"></style>
开启两个窗口就可以测试了,可以基于此代码优化各种细节