利用websocket 来实现聊天功能,紧张是通过以下几点来实现的
一、利用nodejs来实现后端接口
1、起首举行初始化
- const { WebSocketServer } = require("ws"); // 引入WebSocketServer模块
- const Websocket = require("ws");
- const WebSocket = require("ws"); // 引入WebSocket模块
- const onLineList = []; // 定义一个在线用户列表
- // 我们的port是8090
- const wss = new WebSocket.Server({ port: 8080 });
- // 如果有ws就代表初始化成功
- if (wss) {
- console.log("ws初始化成功");
复制代码 2、举行连接 --- 设置进入的欢迎语
- const user = new URL(request.url, `http://${request.headers.host}`).searchParams.get('user');
- console.log(`${user} 已连接`);
- let welCome = JSON.stringify({
- type: "tips",
- content: "欢迎加入聊天室,现在我们开始畅聊吧"
- });
- ws.send(welCome, { binary: false });
复制代码 2)举行注册消息的变乱
- ws.on("message", async function message(data) {
- const message = JSON.parse(data); // 将收到的数据解析为JSON格式
- switch (
- message.type // 根据消息类型进行不同的处理
- ) {
- case "init":
- if (message.userId) {
- // 如果消息中包含用户id
- // 为当前的用户 ws链接绑定 用户id,用于用户断开连接时,改变用户状态
- ws.userId = message.userId;
- // 上线
- keepLatestOnlineList("onLine", message);
- }
- break;
- case "message":
- wss.clients.forEach(client => {
- // 遍历所有客户端
- if (!message.timestamp) {
- message.timestamp = new Date().toISOString();
- }
- if (client.readyState === Websocket.OPEN) {
- // 如果客户端处于打开状态
- client.send(JSON.stringify(message), { binary: false }); // 发送消息
- }
- });
- break;
- default:
- break;
- }
- });
复制代码
3)被动断开说明用户已经脱离网站了,维护在线的列表
- ws.on("close", function() {
- keepLatestOnlineList("close", { userId: ws.userId });
- });
- function keepLatestOnlineList(type, message) {
- let index = onLineList.findIndex(item => item.userId === message.userId); // 在在线列表中查找用户
- switch (type) {
- case "onLine":
- if (index === -1) {
- // 如果用户不在在线列表中,则添加用户
- onLineList.push({ userId: message.userId });
- }
- break;
- case "close":
- if (index !== -1) {
- // 如果用户在在线列表中,则删除用户
- onLineList.splice(index, 1);
- console.log("有客户被断开");
- }
- break;
- default:
- break;
- }
- }
- }
复制代码
二、 设置前端页面
1)模板部分
- <template>
- <div class="app">
- <div class="chat_container">
- <div class="main_content_header">实时聊天</div>
- <div class="chat-room">
- <div class="message-item" v-for="(item, index) in messageList" :key="index">
- <div v-if="item.isSystem" class="system-message">
- {{ formatSendTime(item.timestamp) }}
- </div>
- <!-- 左边通新内容 -->
- <div class="flex-left" v-if="item.userId !== userInfo.userId">
- <!--其他人的 头像 -->
- <div class="avater">
- <el-avatar src="https://picsum.photos/200/300"></el-avatar>
- </div>
- <div class="message-content">{{ item.content }}</div>
- </div>
- <div class="flex-right" v-else>
- <!--自己的 头像 -->
- <div class="message-content">{{ item.content }}</div>
- <div class="avater">
- <el-avatar>
- <img src="../../../assets/images/avater.jpg" alt="">
- </el-avatar>
- </div>
- </div>
- </div>
- </div>
- <div class="send-box">
- <el-input type="text" v-model="yourMessage" />
- <el-button type="primary" @click="sendMesage">发送</el-button>
- </div>
- </div>
- </div>
- </template>
复制代码
2)逻辑部分
- <script setup >
- import { onMounted, ref } from 'vue'
- const yourMessage = ref('')
- const messageList = ref([])
- let ws = null
- const userInfo = ref({
- userId: ""
- })
- const user = ref(sessionStorage.getItem('user'))
- // 发送消息
- function sendMesage() {
- const timestamp = new Date().toISOString()
- if (yourMessage.value) {
- ws.send(JSON.stringify({
- type: "message",
- isSystem: true,
- userId: userInfo.value.userId,
- content: yourMessage.value,
- timestamp: timestamp, // 添加时间戳
- })
- )
- yourMessage.value = ''
- }
- }
- const initWebSocket = () => {
- ws = new WebSocket(`ws://localhost:4090?user=${String(user.value)}`)
- ws.onopen = () => {
- console.log('链接成功')
- ws.send(JSON.stringify({
- type: "init",
- isSystem: true,
- userId: userInfo.value.userId,
- content: '欢迎来到聊天室',
- })
- )
- }
- ws.onmessage = (e) => {
- const message = JSON.parse(e.data)
- switch (message.type) { // 根据消息类型进行不同的操作
- case "tips":
- console.log(message.content) // 如果消息类型为tips,则打印消息内容
- case 'message':
- messageList.value.push(message) // 如果消息类型为message,则将消息添加到消息列表中
- console.log(messageList.value) // 打印消息列表
- break;
- case 'onlineList':
- onlineList.value = message.onlineList // 如果消息类型为onlineList,则将在线用户列表赋值给onlineList
- break;
- }
- }
- ws.onclose = () => {
- console.log('连接关闭')
- }
- ws.onerror = () => {
- }
- }
- onMounted(() => {
- userInfo.value.userId = new Date().getTime().toString().slice(8)
- initWebSocket()
- })
- // 时间格式化
- const formatSendTime = (sendTime) => {
- const now = new Date();
- const sendDate = new Date(sendTime);
- const timeDiff = now - sendDate;
- const oneDay = 24 * 60 * 60 * 1000;
- if (timeDiff < 0) {
- return "Invalid time"; // 或者其他错误处理
- }
- if (timeDiff < oneDay) {
- return "今天" + formatTime(sendDate);
- }
- return sendDate.toLocaleDateString("zh-CN") + " " + formatTime(sendDate);
- };
- const formatTime = (date) => {
- const hours = date.getHours().toString().padStart(2, "0");
- const minutes = date.getMinutes().toString().padStart(2, "0");
- return hours + ":" + minutes;
- };
- </script>
复制代码
3)样式部分
完备代码
nodejs 部分
- const { WebSocketServer } = require("ws"); // 引入WebSocketServer模块
- const Websocket = require("ws");
- const WebSocket = require("ws"); // 引入WebSocket模块
- //定义一个在线列表
- const onLineList = []
- //设置端口号
- const wss = new WebSocket.Server({ port: 4090 });
- // 如果ws就代表初始化成功
- if(wss){
- console.log('WebSocket初始化成功')
- }
- // 进行连接
- wss.on("connection", function connection(ws, request) {
- // 获取对应的用户名,来进行展示连接
- const user = new URL(request.url, `http://${request.headers.host}`).searchParams.get('user');
- console.log(`${user} 已连接`)
- // 设置欢迎语
- let welCome = JSON.stringify({
- type: "tips",
- content:"欢迎回来~"
- })
- ws.send(welCome, { binary: false });
- ws.on("error", (error) => {
- console.log("WebSocket error:", error);
- })
- //注册收到消息的事件
- ws.on("message", async function message(data) {
- const message = JSON.parse(data);
- switch (message.type) {
- case "init":
- if (message.userId) {
- ws.userId = message.userId;
- keepLatestOnlineList('online',message)
- }
- break;
- case "message":
- wss.clients.forEach(client => {
- // 遍历所有的客户端
- if(!message.timestamp) {
- message.timestamp = new Date().toISOString();
- }
- if (client.readyState === Websocket.OPEN) {
- // 如果客户端处于打开状态
- client.send(JSON.stringify(message), { binary: false }); // 发送消息
- }
- })
- break;
- default:
- break;
- }
- })
- ws.on("close", function() {
- keepLatestOnlineList("close", { userId: ws.userId });
- });
- })
- function keepLatestOnlineList(type, message) {
- let index = onLineList.findIndex(item => item.userId === message.userId); // 在在线列表中查找用户
- switch (type) {
- case "onLine":
- if (index === -1) {
- // 如果用户不在在线列表中,则添加用户
- onLineList.push({ userId: message.userId });
- }
- break;
- case "close":
- if (index !== -1) {
- // 如果用户在在线列表中,则删除用户
- onLineList.splice(index, 1);
- console.log("有客户被断开");
- }
- break;
- default:
- break;
- }
- }
复制代码
完成之后的样式如下
 喜欢点个关注吧~
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |