websocket+node+vite(vue)实现一个简单的聊天

news2024/11/27 10:23:15

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>

开启两个窗口就可以测试了,可以基于此代码优化各种细节

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1096894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp开发H5微信公众号,使用微信的扫一扫等Api试错

记录使用uniapp开发H5微信公众号,有些业务需要用到一些API&#xff0c;比如扫码&#xff0c;h5和微信小程序&#xff0c;app在使用过程中有有些不同&#xff0c;h5使用需要单独引入微信的jsdk,才能使用否则会报错无法使用 引入微信jsdk npm安装 npm install jweixin-module -…

一款优秀的文件外发控制软件 具备哪些优势?

随着越来越多的公司在网上开展业务&#xff0c;网络安全漏洞也相应增加。因此&#xff0c;企业需要保护自己的数据&#xff0c;防止数据泄露&#xff0c;给企业带来损失。近几年来&#xff0c;企业数据泄露事件频发&#xff0c;给许多企业都带来巨大创伤。 乌克兰电力公司在201…

【python入门篇】元组、字典和集合(3)

先来介绍下这三种数据类型&#xff0c;第一个&#xff1a;元组&#xff08;tuple&#xff09;是 python中另一个重要的序列结构&#xff0c;和列表类似&#xff0c;元组也是由一系列按特定顺序排序的元素组成。第二个&#xff1a;python 字典&#xff08;dict&#xff09;是一种…

AIGC|数字时代巨变,创新潮流涌现,万亿市值风口已开!

“2021年至2023年7月期间&#xff0c;AIGC赛道共发生280笔投融资&#xff0c;展现了其高热度与高成长性。在获投的应用与模型层创业项目中&#xff0c;文本、影像、语音平分秋色。”艾瑞咨询在其《2023年中国AIGC产业全景报告》披露国内AIGC的最新投融资情况&#xff0c;这让我…

关于IOC与IOA的学习

[TOC]IOC与IOA学习 IoC 和 IoA&#xff1a;两者有什么区别&#xff1f; IoC 和 IoA 可通过以下四种简单的方法进行区分&#xff1a; 具体工具与动机&#xff1a; IoC 专注于攻击者为实现其意图而使用的特定文件和采取的行动&#xff0c;而 IoA 则专注于这些意图本身。IoC 关…

QT 串口编程 QSerialPort

//创建串口对象QSerialPort s new QSerialPort("/dev/ttySAC2", this);//配置串口信息s->setBaudRate(QSerialPort::Baud9600);//波特率s->setDataBits(QSerialPort::Data8);//数据位s->setStopBits(QSerialPort::OneStop);//奇偶校验s->setParity(QSer…

《向量数据库指南》——Milvus Cloud向量数据库的优势

大禹智库: 随着大模型的爆火,向量数据库也越发成为开发者关注的焦点。为了方便大家更好地了解向量数据库,我们特地推出了《Hello, VectorDB》系列,本文将从宏观角度、向量数据库与其他算法库的区别、技术难点及如何选择向量数据库等方面,带大家认识真正的向量数据库。 在…

simulink创建全局变量MATLAB function引用

matlab版本&#xff1a;2022a 在库浏览器中找到Data Store Memory并放置 双击打开Data Store Memory模块设置变量名 在信号属性中设置初始值、数据类型和信号类型&#xff0c;数据类型和信号类型不能为auto 在记录中勾选“记录数据存储数据” 打开引用该变量的MATLAB function模…

数字时代,VR虚拟展会打造全渠道同步营销新模式

随着经济的快速发展&#xff0c;VR虚拟展会逐步完善&#xff0c;对线下实体展会也产生了重大的影响&#xff0c;在这个数字化时代&#xff0c;展会展览也需要寻找新的表达方式&#xff0c;VR虚拟展会以一种全新的魅力吸引越来越多的观展者。 传统展厅的局限性&#xff1b; 1、…

更新 | 持续开源迅为RK3568驱动指南-驱动基础进阶篇

《iTOP-RK3568开发板驱动开发指南》更新&#xff0c;本次更新内容对应的是驱动&#xff08;第一期_驱动基础-进阶篇&#xff09;视频&#xff0c;后续资料会不断更新&#xff0c;不断完善&#xff0c;帮助用户快速入门&#xff0c;大大提升研发速度。 文档教程更新至驱动基础进…

安捷伦N8482A射频传感器6GHz

安捷伦N8482A射频传感器 N8482A 是 Agilent 使用的 6 GHz 0.1 瓦射频传感器。电子测试设备传感器测量波形的功率&#xff0c;例如多音和调制射频 (RF) 波形。传感器使用二极管检测器收集高度精确的调制测量值。 用于存储校准系数的 EEPROM 消除了手动输入 100 kHz 至 6 GHz 的宽…

java-范型

java—范型 泛型在java中有很重要的地位&#xff0c;无论是开源框架还是JDK源码都能看到它。 毫不夸张的说&#xff0c;泛型是通用设计上必不可少的元素&#xff0c;所以真正理解与正确使用泛型&#xff0c;是一门必修课。 1&#xff0c;范型概述 1&#xff0c;泛型本质 J…

linux中运行springboot jar包,内存占用多运行时报错

错误&#xff1a;Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000794500000, 576716800, 0) failed; 重启程序后过两天还会内存不够 通过top查询内存使用情况&#xff0c;发现占用物理内存1g 目前因为启动多个服务&#xff0c;每个服务默认分配…

sql优化常用

1、explain 输出执行计划 在select语句前加上explain就可以了(MySQL 5.6开始&#xff0c;不仅仅支持select )能够简单分析sql的执行情况&#xff0c;是否走索引等。 type列&#xff0c;连接类型。一个好的SQL语句至少要达到range级别。从最好到最差的连接类型为const、eq_reg、…

无线通信——Mesh体系结构

Mesh体系结构 了解Mesh的体系结构有利于我们后期的理解&#xff01;这里有些简单的知识点以及解释 WMN&#xff1a;WMN就是无线mesh网络&#xff0c;我们一般提到WMN其实特指就是Mesh网络的整个体系结构 STA&#xff1a;客户工作站&#xff0c;这个东西就是用户的设备端&…

OAuth2 refreshToken时只获取到用户名的问题解决

1. grant_type为refresh_token时, authentication.getPrincipal()只获取到了字符串类型的用户名(这种情况下生成的access_token是没有权限的,访问不了正常的有权限校验的接口) , 跟踪源码发现 是 DefaultUserAuthenticationConverter#extractAuthentication中的userDetailsSer…

精密空调别再这样管理了,太麻烦啦!

在现代生活中&#xff0c;空调系统已经成为不可或缺的一部分&#xff0c;特别是在高温季节。然而&#xff0c;空调系统的有效性和效率对于节能、环保和用户舒适性至关重要。为了更好地满足这些需求&#xff0c;精密空调监控系统应运而生。 精密空调监控系统结合了先进的技术&am…

新版pycharm(2023.2.2)修改字体大小

下载了2023新版pycharm&#xff0c;想修改字体&#xff0c;发现找不到之前的setting入口&#xff0c;网上搜索也都是file-setting-editor这些&#xff0c;自己找了找&#xff0c;记录下 2023版pycharm的修改字体大小在file-Manage IDE Settings-Setting Sync… 里面&#xff0…

java幼儿园校园学习资源互助共享平台的设计springboot+vue

幼儿资源共享之家在设计之初也只是想弄个关于幼儿资源的一些物资交换系统&#xff0c;但是仅仅是作为一个进行二手交易类型的网站&#xff0c;用户粘性会出现问题&#xff0c;进而会导致产品可能不会达到预期&#xff0c;甚至开发的小黄鸭幼儿资源共享之家会无法良性生存下去。…

二叉树的最小深度(rust实现)

二叉树的最小深度 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 思路 这道题本质上是考察&#xff1a; 如何遍历二叉树理解什么是深度 对于这两点的考察&am…