当前位置: 首页 > news >正文

来咯来咯webSocket

在项目总目录下 设置socketServe文件夹 里面创建下面两个文件

使用的时候需要开启 node webSocket.cjs

var { Server } = require('ws');
var moment = require('moment');const wss = new Server({port: 8888
});let id = 0;
let onlineMemberList = [];
const defaultUser = 'user';wss.on('connection', function (ws, req) {id++;ws.id = id;let reqUser = req.url.split('?')[1];let name = reqUser && reqUser.split('=')[1];let userName;if (name) {userName = decodeURIComponent(name);} else {userName = defaultUser + id;}const userInfo = {userName: userName,socketId: id,date: moment().format('MMMM Do YYYY, h:mm:ss a')};for (let i = 0; i < onlineMemberList.length; i++) {if (userInfo.userName === onlineMemberList[i].userName) {onlineMemberList[i] = userInfo;wss.clients.forEach(itemWs => {itemWs.send(JSON.stringify(onlineMemberList));});return;}}onlineMemberList.push(userInfo);wss.clients.forEach(itemWs => {itemWs.send(JSON.stringify(onlineMemberList));});ws.on('message', function (data) {console.log(data);const newData = JSON.parse(data);newData.serveDate = moment().format('MMMM Do YYYY, h:mm:ss a');wss.clients.forEach(itemWs => {itemWs.send(JSON.stringify(newData));});});ws.on('close', function (ev) {console.log('客户端断开连接');onlineMemberList = onlineMemberList.filter(item => {return item.socketId !== ws.id;});wss.clients.forEach(itemWs => {itemWs.send(JSON.stringify(onlineMemberList));});console.log(onlineMemberList, 'onlineMemberList');console.log(ws.id, 'ws.id');});ws.on('error', function (ve) {console.log('客户端异常');});
});console.log('webSocket服务已开启,端口为:8888');
{"type": "module"
}

页面展示 监听消息

<template><div class="chating"><div class="chating-wrap"><div class="title">聊天页面</div><div class="chating-content"><div class="chating-body"><div class="chating-list"><ul class="chating-records" ref="chatingList"><div:key="index"v-for="(item, index) in chatingRecords"><liclass="other"v-show="item.nickName != myNickName"><imgalt="用户头像"src="@/assets/logo.svg"/><div class="record-text-wrap"><div class="nick-name">{{item.nickName}}</div><div class="record-text">{{item.message}}</div></div></li><liclass="my"v-show="item.nickName == myNickName"><div class="record-text-wrap"><!-- <div class="nick-name">迷离</div> --><div class="record-text">{{item.message}}</div></div><imgalt="用户头像"src="@/assets/logo.svg"/></li></div></ul></div><div class="chating-btns"><inputclass="input-text"placeholder="请输入聊天内容"type="text"v-model="text"@keydown.native.enter="sendData"/><button@click="sendData"class="send">发送</button></div></div><div class="chating-online-number"><div class="online-num">在线用户{{userList.length}}</div><ul v-if="userList.length > 0"><li:key="index"class="user"v-for="(item, index) in userList"><imgalt="用户头像"src="@/assets/logo.svg"/><span>{{ item.userName }}</span><span v-if="userList.includes(item)">(在线)</span><span v-else>(离线)</span></li></ul><button @click="loginOutHandler">退出群聊</button></div></div></div><divclass="login"v-if="showLogin"><div class="opacity-wrap"><div>用户名:<inputclass="user-name"v-model="userName"/></div><button@click="loginHandler"class="login-btn">登录</button></div></div></div>
</template><script>
export default {data() {return {text: '',socketUrl: 'ws://localhost:8888?userName=',client: null,chatingRecords: [],myNickName: '',userName: '',showLogin: false,userList: [],onlineStatus: false // 添加在线状态变量,默认为 false 表示离线}},created() {console.log('created')// this.initChaing()},mounted() {console.log('mounted')},methods: {/* 初始化聊天,连接socket */initChaing() {let that = thisif (window.WebSocket) {/* webSocket 连接服务器 */this.client = new WebSocket(this.socketUrl + this.myNickName)/* 监听客户端连接 */this.client.onopen = function (ev) {if (ev.type === 'open') {console.log('客户端连接socket服务')that.onlineStatus = true; // 更新在线状态为 true}}/* 监听服务端发送的消息 */this.client.onmessage = function (ev) {let data = JSON.parse(ev.data)/* 用户在线信息接收的是一个jsony数组 */if (data instanceof Array === true) {that.userList = data // 在线用户数量变化} else {/* 聊天信息接收的是一个json对象 */that.chatingRecords.push(data) // 在线用户聊天}}/* 监听服务端关闭 */this.client.onclose = function (ev) {console.log('socket服务已关闭')that.client = null // 客户端或者是服务端断开后,将webSocket实例清除that.onlineStatus = false; // 更新在线状态为 false}/* 监听服务端异常 */this.client.onerror = function () {if (!that.client) {console.log('socket服务连接失败')}that.loginOutHandler()}} else {alert('该浏览器不支持webSocket,请使用主流浏览器,如chrome')}},loginHandler() {this.myNickName = this.userName;this.showLogin = false;this.onlineStatus = true; // 用户登录成功后将在线状态更新为 truethis.initChaing();},loginOutHandler() {this.client.close()this.client = null // 客户端或者是服务端断开后,将webSocket实例清除this.$router.push('/')},sendData() {if (!this.myNickName) {alert('请登录')this.showLogin = truereturn}if(this.text === ''){return}let data = {nickName: this.myNickName, // 将 myNickName 改为 nickNameuid: new Date().getTime(),message: this.text,date: new Date()}if (this.client) {this.client.send(JSON.stringify(data))this.text = ''// 在添加新消息后,将列表容器滚动到底部this.$nextTick(() => {let chatList = this.$refs.chatingList;if (chatList) {// 计算滚动位置,考虑到边距和边框let scrollHeight = chatList.scrollHeight;let clientHeight = chatList.clientHeight;let offset = 54; // 考虑到可能的额外偏移量chatList.scrollTop = scrollHeight - clientHeight + offset;}});} else {console.log('socket服务连接失败,正在重新连接服务..')this.initChaing()}}},beforeDestroy() {this.client.close()}
}
</script><style>
.login {width: 100vw;height: 100vh;position: fixed;top: 0;left: 0;background: rgba(0, 0, 0, 0.6);display: flex;justify-content: center;align-items: center;
}
.opacity-wrap {width: 500px;height: 300px;background: #fff;display: flex;justify-content: center;align-items: center;flex-direction: column;
}
.user-name {font-size: 16px;padding: 5px;text-indent: 10px;
}
.login-btn {font-size: 20px;background: cornflowerblue;color: 20px;margin-top: 30px;color: #fff;border: none;outline: none;padding: 10px 20px;border-radius: 10px;
}
ul {list-style: none;margin: 0;padding: 0;
}
.chating {width: calc(100vw - 200px);max-width: 800px;max-height: 600px;overflow-y: auto;border: 20px solid lightcyan;border-radius: 20px;margin: 0 auto 0;
}
.title {background: cornflowerblue;color: #fff;padding: 5px 0 5px;
}
.chating-content {width: 100%;display: flex;justify-content: space-between;
}
.chating-body {flex: 1;display: flex;flex-direction: column;justify-content: space-between;background: #f3f3f3;
}
.chating-list {flex: 1;border: 1px solid cornflowerblue;
}
.chating-records {padding: 10px;min-height: 300px;max-height: 600px;overflow-y: auto;
}
.chating-records li {margin-bottom: 20px;
}
.chating-records .other {display: flex;justify-content: start;align-items: flex-start;
}
.chating-records .my {display: flex;justify-content: flex-end;align-items: center;
}.chating-records img {width: 36px;height: 36px;/* border-radius: 50%; */margin-right: 15px;background: rgba(228, 157, 228,0.5);
}
.chating-records .my img {margin-right: 0;margin-left: 15px;
}
.chating-records .other .record-text-wrap {display: flex;flex-direction: column;align-items: flex-start;
}
.chating-records .my .record-text-wrap {display: flex;flex-direction: column;align-items: flex-end;
}
.nick-name {font-size: 14px;margin-bottom: 5px;color: #666;
}
.record-text {max-width: 260px;text-align: left;font-size: 14px;padding: 5px;background: #fff;border-radius: 5px;
}.chating-btns {background: burlywood;padding: 10px;display: flex;align-items: center;justify-content: center;
}
.input-text {font-size: 16px;border: none;outline: none;padding: 5px 0 5px 5px;
}
.send {font-size: 16px;border: none;outline: none;padding: 4px 15px;margin-left: 20px;
}.online-num {font-size: 12px;padding-bottom: 15px;
}
.chating-online-number {padding: 15px;height: 100%;
}
.chating-online-number ul {list-style: none;margin: 0;padding: 0;min-width: 120px;max-height: 580px;overflow-y: auto;
}
.user {display: flex;justify-content: space-between;align-content: center;line-height: 20px;font-size: 12px;border-bottom: 1px solid aqua;padding: 10px;margin-bottom: 5px;
}
.user img {width: 20px;height: 20px;border-radius: 50%;margin-right: 5px;
}
</style>

相关文章:

来咯来咯webSocket

在项目总目录下 设置socketServe文件夹 里面创建下面两个文件 使用的时候需要开启 node webSocket.cjs var { Server } require(ws); var moment require(moment);const wss new Server({port: 8888 });let id 0; let onlineMemberList []; const defaultUser user;wss…...

Android CALL关于电话音频和紧急电话设置和获取

获取音频服务&#xff0c;设置音源类型&#xff1a;电话类型和获取最大电话音量&#xff0c;响铃模式 private AudioManager mAudioManager; mAudioManager (AudioManager) getSystemService(AUDIO_SERVICE); mAudioManager.setStreamVolume(AudioManager.STREAM_VOIC…...

【春秋云镜】CVE-2023-23752

目录 CVE-2023-23752漏洞细节漏洞利用示例修复建议 春秋云镜&#xff1a;解法一&#xff1a;解法二&#xff1a; CVE-2023-23752 是一个影响 Joomla CMS 的未授权路径遍历漏洞。该漏洞出现在 Joomla 4.0.0 至 4.2.7 版本中&#xff0c;允许未经认证的远程攻击者通过特定 API 端…...

C#-__DynamicallyInvokable

[__DynamicallyInvokable] 属性是用于 .NET Framework 中的特性之一。这个特性通常用于标记在动态语言运行时中可以进行调用的方法或属性。 当一个方法或属性被标记为 [__DynamicallyInvokable]&#xff0c;它表明这个成员在动态语言的环境中是可调用的。换句话说&#xff0c;…...

2024年最新10款顶级项目管理软件排行

项目管理软件在现代项目管理中扮演着至关重要的角色&#xff0c;它不仅仅是一个工具&#xff0c;更是一种高效、系统化的方法来管理和优化项目流程&#xff0c;帮助项目经理和团队成员快速了解项目状态&#xff0c;加速项目进展。 进度猫 进度猫是一款以甘特图为向导的轻量级…...

Python NLTK进阶:深入自然语言处理

目录 Python NLTK进阶&#xff1a;深入自然语言处理 1. 文本处理技术 1.1 命名实体识别&#xff08;NER&#xff09; 1.2 共指消解 2. 语义分析 2.1 语义角色标注&#xff08;SRL&#xff09; 2.2 词义消歧&#xff08;Word Sense Disambiguation&#xff09; 3. 机器学…...

【React 的理解】

谈一谈你对 React 的理解 对待这类概念题&#xff0c;讲究一个四字口诀“概用思优”&#xff0c;即“讲概念&#xff0c;说用途&#xff0c;理思路&#xff0c;优缺点&#xff0c;列一遍” 。 React 是一个网页 UI 框架&#xff0c;通过组件化的方式解决视图层开发复用的问题&a…...

软件压力测试有多重要?北京软件测试公司有哪些?

软件压力测试是一种基本的质量保证行为&#xff0c;它是每个重要软件测试工作的一部分。压力测试是给软件不断加压&#xff0c;强制其在极限的情况下运行&#xff0c;观察它可以运行到何种程度&#xff0c;从而发现性能缺陷。 在数字化时代&#xff0c;用户对软件性能的要求越…...

十四届蓝桥杯STEMA考试Python真题试卷第二套第五题

来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第五题 本题属于迷宫类问题,适合用DFS算法解决,解析中给出了Python中 map() 和列表推导式的应用技巧。最后介绍了DFS算法的两种常见实现方式——递归实现、栈实现,应用场景——迷宫类问题、图的连通性、树的遍历、拓朴排…...

虚拟机 Ubuntu 扩容

文章目录 一、Vmware 重新分配 Ubuntu 空间二、Ubuntu 扩容分区 一、Vmware 重新分配 Ubuntu 空间 先打开 Vmware &#xff0c;选择要重新分配空间的虚拟机 点击 编辑虚拟机设置 &#xff0c;再点击 硬盘 &#xff0c;再点击 扩展 选择预计扩展的空间&#xff0c;然后点击 扩展…...

内网远程连接解决方案【Frp】

1、从https://github.com/fatedier/frp/releases下载需要的版本&#xff0c;如 frp_0.61.0_linux_amd64.tar.gz 2、解压tar -xvf frp_0.61.0_linux_amd64.tar.gz 3、配置服务端【外网云主机】&#xff0c;修改ftps.toml文件&#xff1a; bindPort 7000 vhostHTTPPort8000…...

浙江欧瑞雅装饰材料有限公司:空间的艺术,定制的智慧!

浙江欧瑞雅装饰材料有限公司&#xff1a;空间的艺术&#xff0c;定制的智慧&#xff01;在追求生活品质与空间利用并重的当下&#xff0c;浙江欧瑞雅装饰材料有限公司以其卓越的全屋定制服务&#xff0c;成为了众多家庭优化居住环境的理想选择。这家公司&#xff0c;凭借其深厚…...

jfrog artifactory oss社区版,不支持php composer私库

一、docker安装 安装环境&#xff1a;centos操作系统&#xff0c;root用户。 如果是mac或ubuntu等操作系统的话&#xff0c;会有许多安装的坑等着你。 一切都是徒劳&#xff0c;安装折腾那么久&#xff0c;最后还是不能使用。这就是写本文的初衷&#xff0c;切勿入坑就对了。 …...

华为OD机试真题-用户调度问题-2024年OD统一考试(E卷)

最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。 题目描述 在通信系统中,一…...

前端与后端长连接 方法

1、SSE 一、SSE的主要特点 单向通信​&#xff1a;SSE是服务器向客户端的单向通信&#xff0c;客户端不能直接通过SSE向服务器发送消息。文本数据流​&#xff1a;SSE传输的主要是文本数据&#xff08;通常是JSON格式&#xff09;&#xff0c;不适合二进制数据。自动重连​&a…...

建议AI产品经理面试准备到这个程度再去

AI产品经理的面试整体的难度不高&#xff0c;和面试官探讨了很多关于做AI平台的方向和思考&#xff0c;其中AI智能客服的搭建被问到的次数最多&#xff01;面试官也解释了很多他们现在碰到的业务问题和解决方案&#xff0c;收获还是很多的~ ⏭️AI智能客服项目如下 1️⃣ 【预…...

智能交通的未来:深度学习如何改变车辆检测游戏规则

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

家具制造的效率与美观并重,玛哈特矫平机让家具产品更具竞争力。

在家具制造业中&#xff0c;效率与美观度的双重追求一直是企业关注的焦点。一方面&#xff0c;高效率的生产流程能够缩短交货周期&#xff0c;降低成本&#xff0c;提升企业的市场竞争力&#xff1b;另一方面&#xff0c;美观大方的家具设计则能吸引消费者的目光&#xff0c;提…...

交叉编译gcc

文章目录 前言下载gcc下载依赖项下载其他依赖项 configure选项--enable-languagesCXX和CXX_FOR_TARGETCFLAGS和CXXFLAGS--with-build-time-tools 使用小结 前言 前一阵用qemu做了个基于virt板卡的虚拟机&#xff0c;在不断完善&#xff0c;这两天想添加一个gcc进去&#xff0c…...

[VUE]框架网页开发1 本地开发环境安装

前言 其实你不要看我的文章比较长&#xff0c;但是他就是很长&#xff01;步骤其实很简单&#xff0c;主要是为新手加了很多解释&#xff01; 步骤一&#xff1a;下载并安装 Node.js 访问 Node.js 官网&#xff1a; Node.js — Download Node.js 下载 Windows 64 位版本&…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...