WebSocket在node端和客户端的使用
摘要
如果想要实现一个聊天的功能,就会想到使用WebSocket来搭建。那如果没有WebSocet的时候,我们会以什么样的思路来实现聊天功能呢?
假如有一个A页面 和 B页面进行通信,当A发送信息后,我们可以将信息存储在文件或者数据库里。
但是B页面并不知道A发送了信息,所以如果想要让B 页面实时的去展示A发送的信息,我们只能在B页面设置一个定时器,在定时器中一直去查询文件或者数据库的信息,如果有新的消息,那么就在B页面进行展示,同理,在A页面也要以相同的方法去实现。

对于这个方法,需要不停的去轮训,耗费了大量的空间和时间,那如果在A 发送消息后,B页面可以主动的接收到对应的消息,就不需要在定时器中去不停的查找了。
WebSocket,就是为了解决这个问题出现的。WebSocket支持双向通信,服务器和客户端之间可以随时互相发送信息,实时性更强。
1. ws模块
在node中,大家对于fs模块,http模块应该已经不陌生了。这里我们需要引入的模块是ws模块,需要通过npm install进行安装。
WS模块是一个WebSocket协议的实现,它允许客户端(一般是浏览器)和服务器之间建立持久连接,进行实时双向通信。这种持久连接可以使得数据传输更加高效,适用于需要实时交互的应用场景,如在线聊天室、游戏等。
现在我们简单的使用一下:
新建一个文件夹,npm init初始化,再npm install ws
在文件夹下新建一个index.js
const WebSocket = require('ws')const wss = new WebSocket.Server({port: 3004});wss.on('connection', (ws) => {//如果有客户端连接,就会进入这个回调console.log('Client connected');ws.on('message', (message) => {// 如果有客户端发送消息,就会进入这个回调console.log(message.toString());})
})
这样一个简单的ws的node端就实现了。现在我们新建一个html文件:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div style="width: 200px;height:300px;background: #e2e2e2;margin-bottom: 20px;"><span></span></div><input type="text"><button>发送</button><script>// 创建ws模块var ws = new WebSocket(`ws://localhost:3004`);// 建立连接ws.onopen = function () {// 客户端向服务端发送消息ws.send('hello word');console.log('已连接');}</script>
</body>
</html>
这样就是一个简单的客户端向服务端发送消息的模型。
2.从服务端发往客户端
上面的代码主要实现了从客户端到服务端,但这也是正常思路。我们肯定是希望从服务端到客户端。
所以我们要在服务端接受到消息后,也往客户端发送消息:
const WebSocket = require('ws')const wss = new WebSocket.Server({port: 3004});wss.on('connection', (ws) => {console.log('Client connected');ws.on('message', (message) => {console.log(message.toString());// 服务端向客户端发送消息ws.send('hello word too')})
})
在客户端里,我们通过onmessage的回调来进行接受:
<script>var ws = new WebSocket(`ws://localhost:3004`);ws.onopen = function () {ws.send('hello word');console.log('已连接');}ws.onmessage = async function(mes) {// 接受服务端发送的消息console.log(mes.data)}</script>
3.对于不同的客户端,返回不同的信息
那如果想实现出一个聊天的功能,服务端接受到A的消息,要给B发送消息。
上面的代码似乎只能,谁给服务端发,服务端就给谁返回。
所以在node的代码里,我们需要每次建立连接的时候,将对应的ws保存起来,然后根据客户端的信息,用指定的ws去返回信息。
现在我们如果有两个html,每个html在初始化页面的时候,给服务端发送一个消息,代表自己已经连接的信息。
点击按钮的时候,给服务端发送的信息,要携带希望传递的客户端的信息。
页面1:
<script>var ws = new WebSocket(`ws://localhost:3004`);ws.onopen = function () {ws.send(JSON.stringify({name: 'zhangsan', message: 'init'}));console.log('已连接');}ws.onmessage = async function(mes) {console.log(mes.data)}function click() {const value = input.value;ws.send(JSON.stringify({name: 'lisi', message: '你好lisi'}))}</script>
页面2:
<script>var ws = new WebSocket(`ws://localhost:3004`);ws.onopen = function () {ws.send(JSON.stringify{name: 'lisi', message: 'init'}));console.log('已连接');}ws.onmessage = async function(mes) {console.log(mes.data)}function click() {const value = input.value;ws.send(JSON.stringify({name: 'zhangsan', message: '你好zhangsan'}))}</script>
在node端中,我们要根据message是否为init,进行判断。
const WebSocket = require('ws')const wss = new WebSocket.Server({port: 3004});
const wsList = {}wss.on('connection', (ws) => {ws.on('message', (message) => {const result = JSON.parse(message);// 页面初始化的时候,使用wsList将ws进行缓存if(result.message === 'init') {wsList[result.name] = ws;}else {// 根据name的值来给指定的客户端发送信息const ws = wsList[result.name];ws.send(result.message)}})ws.on('close', () => {Object.keys(wsList).forEach(item => {// 当websoket关闭的时候,要清空对应的wsif(wsList[item].readyState !== 1) {delete wsList[item]}})})
})
以上就是对应ws模块,和WebSocket的简单阐述。
相关文章:
WebSocket在node端和客户端的使用
摘要 如果想要实现一个聊天的功能,就会想到使用WebSocket来搭建。那如果没有WebSocet的时候,我们会以什么样的思路来实现聊天功能呢? 假如有一个A页面 和 B页面进行通信,当A发送信息后,我们可以将信息存储在文件或者…...
ENVI IDL:如何将txt文本文件转化为GeoTIFF文件?
01 前言 此处的文本文件形式如下: 里面包含了众多点位信息(不是站点数据),我们需要依据上述点的经纬度信息放到对应位置的像素点位置,放置完后如下: 可以发现,还存在部分缺失值,我们…...
北邮22级信通院数电:Verilog-FPGA(9)第九周实验(2)实现下降沿触发的JK触发器(带异步复位和置位功能)
北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 JK.v module JK (input clk,input J,input K,input…...
pyqt5UI同步加载
问题记录:pyqt5 怎样实现修改ui而不改变py代码,例如一个文件存入ui代码,另一个文件引入ui代码 起因:由于在写一个漏扫工具,由于ui的平频繁改动导致主体代码结构变动,所以先有没有方法能够不改变主题代码&am…...
CentOS 7 安装 Redis 5 (单机 6379)
CentOS 7 安装 Redis 5 (单机 6379) 自己准备好 Redis 5 的安装包并上传至 /opt/ 下的 redis 文件夹下: cd /opt mkdir redis cd redis准备好 Redis 所需的编译环境: yum -y install gcc yum -y install gcc-c解压上传的 Redis…...
sqlplus set参数大区
通过设置不同的SET参数,可以定制SQLPlus的行为和输出格式: SET 参数描述SET AUTOTRACE显示SQL语句的执行计划和统计信息,用于性能优化。SET FEEDBACK控制是否显示SQL语句执行的行数,可提高结果可读性。SET LINESIZE设置每行的最大…...
从0到0.01入门React | 006.精选 React 面试题
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…...
GeoTools实战指南: 处理矢量文件中多多边形的MultiPolygon空洞问题
目录 GeoTools实战指南: 处理矢量文件中多多边形的MultiPolygon空洞问题背景思路分析代码实现引入依赖读取并遍历矢量文件处理并“缝合”一个多边形的内外环结果保存到新的矢量文件中完整代码效果展示仓库代码地址GeoTools实战指南: 处理矢量文件中多多边形的MultiPolygon空洞问…...
javaSE学习笔记(五)集合框架-Collection,List,Set,Map,HashMap,Hashtable,ConcurrentHashMap
目录 四、集合框架 1.集合概述 集合的作用 集合和数组的区别 集合继承体系 数组和链表 数组集合 链表集合 2.Collection 方法 集合遍历 并发修改异常 3.List List集合的特有功能(核心是索引) 集合遍历 并发修改异常产生解决方案ListItera…...
web3 React dapp项目通过事件从区块链中拿到 已取消 已完成 和所有的订单数据 并存入redux中
好 上文web3通过antd 在React dapp中构建订单组件基本结构我们算是把一个基本的订单组件展示做出来了 然后 我们继续 起一下环境先 ganache 终端运行 ganache -dMetaMask 登录一下 然后 打开项目 发布一下合约 truffle migrate --reset然后 运行一下 测试脚本 转入交易所 E…...
25、Flink 的table api与sql之函数(自定义函数示例)
Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…...
MybatisPlus —注解汇总
本文将介绍 MybatisPlus 注解包相关类详解(更多详细描述可点击查看源码注释) 注解类包源码:👉 mybatis-plus-annotation(opens new window) 一、#TableName(opens new window) 描述:表名注解,标识实体类对…...
flink对状态ttl进行单元测试
背景 在处理键值分区状态时,使用ttl设置过期时间是我们经常使用的,但是任何代码的修改都需要首先进行单元测试,本文就使用单元测试来验证一下状态ttl的设置是否正确 测试状态ttl超时的单元测试 首先看一下处理函数: // 处理函…...
Mac电脑安装打印机驱动
1.在打印机背面找到型号,当想要安装的驱动在官网找不到时可直接搜索该系列:比如MF系列 2.安装完成后需要添加打印机 当打印机和电脑在同一个WiFi下的时候查找打印机IP,输入IP后可以查到对应的打印机,添加后即可使用...
C语言 每日一题 牛客网 11.13 Day17
找零 Z国的货币系统包含面值1元、4元、16元、64元共计4种硬币,以及面值1024元的纸币。 现在小Y使用1024元的纸币购买了一件价值为N(0 < N≤1024)的商品,请问最少他会收到多少硬币? 思路 运用if语句进行判断分类 代码实现 int main() {…...
python读取npy和dat文件信息
前言 python读取.dat 和 .npy 数据 Code import numpy as np def read_dat():print("read data .dat \n")path "./c1_input.dat"data np.fromfile(path, np.float16).reshape(4,38,800)print(fdata :{data}, data shape:{data.shape}, data dtype:{d…...
【Git】第四篇:基本操作(理解工作区、暂存区、版本库)
Git 工作区、暂存区和版本库 工作区:就是我们创建的本地仓库所在的目录暂存区: stage或index,一般放在.git(可隐藏文件)目录下的index文件(.git/index)中,所以我们把暂存区有时候也叫做索引(in…...
Word转PDF简单示例,分别在windows和centos中完成转换
概述 本篇博客以简单的示例代码分别在Windows和Linux环境下完成Word转PDF的文档转换。 文章提供SpringBoot Vue3的示例代码。 文章为什么要分为Windows和Linux环境? 因为在如下提供的Windows后端示例代码中使用documents4j库做转换,此库需要调用命令行…...
推荐收藏!大模型算法工程师面试题来了(附答案)
自 ChatGPT 在去年 11 月底横空出世,大模型的风刮了整一年。 历经了百模大战、Llama 2 开源、GPTs 发布等一系列里程碑事件,将大模型技术推至无可争议的 C 位。基于大模型的研究与讨论,也让我们愈发接近这波技术浪潮的核心。 最近大模型相关…...
线程与进程
文章目录 什么是进程?什么是线程?线程、进程的区别多线程编程 什么是进程? 进程(Process)是计算机中的程序关于数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。简单来说,进程就…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
