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

node.js中ws模块创建服务端和客户端

一、WebSocket出现的原因

1、Http协议发布REST API 的不足:
每次请求响应完成之后,服务器与客户端之间的连接就断开了,如果客户端想要继续获取服务器的消息,必须再次向服务器发起请

求。这显然无法适应对实时通信有高要求的场景。

2、改善http的不足:Web通信领域出现了一些其他的解决方案,如轮询、长轮询、服务器推送事件、WebSocket
(1)轮询:就是重复发送新的请求到服务器。如果服务器没有新的数据,就发送适当的指示并关闭连接。然后客户端等待一段时间

(比如间隔一秒),再发送另一个请求。这种实现方式相对比较简单,无须做过多的更改。但缺点是轮询的间隔过长,会导致用户不能及

时接收到更新的数据;轮询时间过短,会导致查询请求过多,增加服务器端的负担。

(2)长轮询:客户端发送一个请求到服务器,如果服务器端没有新的数据,就保持这个连接直到有数据。一旦服务器端有了数据

(消息)给客户端,它就使用这个连接发送数据给客户端,接着连接关闭

(3)服务器推送事件:Server-Sent Events(SSE),SSE通常重用一个连接处理多个消息(事件)。SSE还定义了一个专门的媒体类

型,用于描述一个从服务端发送到客户端的简单格式。

(4)WebSocket:提供了一个真正的全双工连接。发起者是一个客户端,发送一个带特殊HTTP头的请求到服务端,通知服务器。

该方案的优点是属于html5标准,已经被大多数浏览器支持,而且是真正的全双工,性能比较好,其缺点是实现起来比较复杂,需要对ws

协议专门处理。

二、Node使用ws创建WebSocket服务器

1、Node.js原生API没有提供对WebSocket的支持,需要安装第三方包才能使用WebSocket功能

2、ws模块:是一个用于支持WebSocket客户端和服务器的框架。它易于使用,功能强大,且不依赖于其他环境

3、安装ws:npm install ws

4、创建WebSocket服务器:

 //创建一个WebSocket服务器,在8080端口启动const WebSocket = require('ws')const server = new WebSocket.Server({port:8080})

5、WebSocket.Server(options[,callback])方法中options对象所支持的参数

(1)host:绑定服务器的主机名

(2)port:绑定服务器的端口号

(3)backlog:挂起连接队列的最大长度

(4)server:预先创建的node.js http/s服务器

(5)verifyClient:可用于验证传入连接的函数

(6)handleProtocols:可用于处理WebSocket子协议的函数

(7)path:仅接受与此路径匹配的连接

(8)noServer:不启用服务器模式

(9)clientTracking:指定是否跟踪客户端

(10)perMessageDeflate:启用/禁用消息压缩

(11)maxPayload:允许的最大消息大小(以字节为单位)

三、监听连接:ws通过connection事件来监听连接

server.on('connection',function connection(ws,req){const ip = req.socket.remoteAddressconst port = req.socket.remotePortconst clientName = ip + port​console.log('%s is connected ',clientName)})//只要有WebSocket连接到该服务器,就会触发'connection'事件;req对象可以用来获取客户端的信息,如ip、端口号//获取所有已连接的客户端信息,则可以使用server.clients数据集

四、发送数据:ws通过send()方法来发送数据

 /* send(data [,options][,callback])data:发送的数据options对象:(1)compress:指定数据是否需要压缩。默认为true(2)binary:指定数据是否通过二进制传送。默认是自动检测(3)mask:指定是否应遮罩数据。(4)fin:指定数据是否为消息的最后一个片段。默认为true*/server.on('connection',function connection(ws,req){const ip = req.socket.remoteAddressconst port = req.socket.remotePortconst clientName = ip + port​console.log('%s is connected ',clientName)​ws.send('Welcome ' + clientName)})

五、接收数据:ws通过message事件来接收数据。当客户端有消息发送给服务器时,服务器就能够触发该消息

server.on('connection',function connection(ws,req){const ip = req.socket.remoteAddressconst port = req.socket.remotePortconst clientName = ip + port​console.log('%s is connected ',clientName)​ws.send('Welcome ' + clientName)​ws.on('message',function incoming(message){console.log('received: %s from %s',message,clientName)server.clients.forEach(function each(client){if(client.readyState === WebSocket.OPEN){client.send(clientName +" -> " + message)}})})})

六、准备的状态:ws中WebSocket类具有以下4中准备状态

1、CONNCETION:值为0,表示连接还没有打开

2、OPEN:值为1,表示连接已经打开,可以通信了

3、CLOSING:值为2,表示连接正在关闭

4、CLOSED:值为2,表示连接已经关闭

server.clients.forEach(function each(client){if(client.readyState === WebSocket.OPEN){client.send(clientName +" -> " + message)}})

七、关闭WebSocket服务器:通过监听close事件关闭服务器

 server.on('close',function close(){console.log('disconnected')})

案例
1、服务器端:server.js

const WebSocket = require('ws')const server = new WebSocket.Server({port:8080})​server.on('open',function open(){console.log('connected')})​server.on('close',function close(){console.log('disconnected')})​server.on('connection',function connection(ws,req){const ip = req.socket.remoteAddressconst port = req.socket.remotePortconst clientName = ip + port​console.log('%s is connected ',clientName)​ws.send('Welcome ' + clientName)​ws.on('message',function incoming(message){console.log('received: %s from %s',message,clientName)server.clients.forEach(function each(client){if(client.readyState === WebSocket.OPEN){client.send(clientName +" -> " + message)}})})})

2、客户端:

<!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><script>var socketif (!window.WebSocket) {window.WebSocket = window.MozWebSocket}if(window.WebSocket){socket = new WebSocket("ws://localhost:8080/ws")socket.onmessage = function(event){var ta = document.getElementById('responseTest')ta.value = ta.value + '\n' + event.data}socket.onopen = function(event) {var ta = document.getElementById('responseTest')ta.value = '连接开启!'}​socket.onclose = function(event) {var ta = document.getElementById('responseTest')ta.value = '连接关闭!'}}else{alert('你的浏览器不支持WebSocket')}function send(message){if(!window.WebSocket){return}if(socket.readyState === WebSocket.OPEN){socket.send(message)}else{alert('连接没有开启')}}</script><form onsubmit="return false"><h3>WebSocket 聊天室:</h3><textarea  id="responseTest" style="width: 500px;height: 300px;"></textarea><br><input type="text" name="message" style="width: 300px;" value="Welcome to woniuxy.com"><input type="button" value="发送消息" onclick="send(this.form.message.value)"><input type="button" value="清空聊天记录" onclick="javascript:document.getElementById('responseTest').value=''"></form></body></html>

相关文章:

node.js中ws模块创建服务端和客户端

一、WebSocket出现的原因 1、Http协议发布REST API 的不足&#xff1a; 每次请求响应完成之后&#xff0c;服务器与客户端之间的连接就断开了&#xff0c;如果客户端想要继续获取服务器的消息&#xff0c;必须再次向服务器发起请 求。这显然无法适应对实时通信有高要求的场景…...

kubernates-1.26.1 kubeadm containerd 单机部署

k8s1.26 kubeadm containerd 安装 kubeadm init 时提示 containerd 错误 failed to pull image “k8s.gcr.io/pause:3.6” 报错日志显示containerd pull时找不到对应的pause版本&#xff0c;而不是registry.k8s.io/pause:3.9 [rootk8s-master containerd]# kubeadm init --k…...

如何在 iPhone 上恢复已删除的通话记录/通话记录

您的通话记录/通话记录可能很重要&#xff0c;尤其是当您想要拨打之前联系过但未保存的号码时。如果您碰巧删除了通话记录&#xff08;有意或无意&#xff09;&#xff0c;本指南将帮助您了解如何检索它们并找回您需要使用的所有记录。我们将根据您的情况和您拥有的工具讨论不同…...

Canonical为所有支持的Ubuntu LTS系统发布了新的Linux内核更新

导读Canonical近日为所有支持的Ubuntu LTS系统发布了新的Linux内核更新&#xff0c;以解决总共19个安全漏洞。新的Ubuntu内核更新仅适用于长期支持的Ubuntu系统&#xff0c;包括Ubuntu 22.04 LTS&#xff08;Jammy Jellyfish&#xff09;、Ubuntu 20.04 LTS&#xff08;Focal F…...

MS9122是一款USB单芯片投屏器,内部集成了USB2 0 控制器和数据收发模块、HDMI 数据接口和音视频处理模块。MS9122可以通过USB接口显示

MS9122是一款USB单芯片投屏器&#xff0c;内部集成了USB2.0 控制器和数据收发模块、HDMI 数据接口和音视频处理模块。MS9122可以通过USB接口显示或者扩展PC、智能手机、平板电脑的显示信息到更大尺寸的显示设备&#xff0c;支持HDMI视频接口。 主要功能特征 HDMI v1.4兼容 最大…...

C++学习笔记-数据抽象

简单的说&#xff0c;数据抽象是用来描述数据结构的。数据抽象就是 ADT。一个 ADT 主要表现为它支持的一些操作&#xff0c;比方说 stack.push、stack.pop&#xff0c;这些操作应该具有明确的时间和空间复杂度。另外&#xff0c;一个 ADT 可以隐藏其实现细节&#xff0c;比方说…...

【Android】Android开发笔记(一)

【Android】Android开发笔记&#xff08;一&#xff09; 在Android Studio中import module和delete moduleimport moduledelete moduleAndroid Studio中App&#xff08;Module&#xff09;无法正常运行在实机上测试App一些基本概念App的工程结构结语在Android Studio中import m…...

C语言数据结构(二)—— 受限线性表 【栈(Stack)、队列(Queue)】

在数据结构逻辑层次上细分&#xff0c;线性表可分为一般线性表和受限线性表。一般线性表也就是我们通常所说的“线性表”&#xff0c;可以自由的删除或添加结点。受限线性表主要包括栈和队列&#xff0c;受限表示对结点的操作受限制。一般线性表详解&#xff0c;请参考文章&…...

线程安全之synchronized和volatile

目录 1.线程不安全的原因 2.synchronized和volatile 2.1 synchronized 2.1.1 synchornized的特性 2.1.2 synchronized使用示例 2.2 volatile 我们先来看一段代码&#xff1a; 分析以上代码&#xff0c;t1和t2这两个线程的任务都是分别将count这个变量自增5000次&#xff…...

量子计算对网络安全的影响

量子计算的快速发展&#xff0c;例如 IBM 的 Quantum Condor 处理器具有 1000 个量子比特的容量&#xff0c;促使专家们宣称第四次工业革命即将实现“量子飞跃”。 量子计算机的指数处理能力已经受到政府和企业的欢迎。 由于从学术和物理原理到商业可用解决方案的不断转变&am…...

MyBatis——增删改查操作的实现

开启mybatis sql日志打印 可以在日志中看到sql中执行的语句 在配置文件中加上下面这几条语句 mybatis.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl logging.level.com.example.demodebug查询操作 根据用户id查询用户 UserMapper&#xff1a; User…...

【7】linux命令每日分享——cat查看文件内容

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…...

新氧2023年财务业绩预测:退市风险大幅降低,收入增长将放缓

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 公司进展 与新氧&#xff08;SY&#xff09;有关的两个重要积极进展值得一提。 第一个积极进展是新氧的退市风险已在很大程度上降低。 2023年1月6日&#xff0c;新氧披露&#xff0c;它已经“重新符合纳斯达克规定的股价每…...

C++使用shared_ptr与weak_ptr轻松管理内存

智能指针之shared_ptr与weak_ptr前言智能指针实例分析前言 C与其他语言的不同点之一就是可以直接操作内存&#xff0c;这是一把双刃剑&#xff0c;直接操作内存可以提高开发的灵活度&#xff0c;开发人员在合适的时机申请内存&#xff0c;在合适的时机释放内存&#xff0c;减少…...

Buuctf reverse [FlareOn4]IgniteMe 题解

一. 查壳 无壳32位程序 二. ida打开 GetStdHandle函数根据微软官方文档可以得知是获取标准输入/输出/错误的句柄 参数里的 0xFFFFFFF6转换一下是4294967286, 对应(DWORD) -10 所以这里的WriteFile函数实际上是实现了printf的功能 sub_4010F0()函数 其功能是通过ReadFile函数读取…...

ChatGPT懂SAP吗?跟ChatGPT聊完后,我暂时不担心会失业

我弄了个ChatGPT账号。随便问了一下他SAP的问题。贴出来跟大家分享一下。 问题1&#xff1a;我是 SAP 开发工程师&#xff0c;你有什么可以帮到我。 作为一个语言模型&#xff0c;我可以为您提供关于SAP开发的一般性建议&#xff0c;以及关于如何使用SAP软件的一些技巧。以下是…...

Communications link failure 解决方法 !!!

Communications link failure 解决方法 最近在使用mybatis逆向生成的时候遇到了link failure的问题, 这里记录解决方法 文章目录Communications link failure 解决方法generatorConfig 里的数据库链接或数据库或密码或账户填写错误mysql响应时间设置太短, 还没等链接上就关闭连…...

pytorch入门2--数据预处理、线性代数的矩阵实现、求导

数据预处理是指将原始数据读取进来使得能用机器学习的方法进行处理。 首先介绍csv文件&#xff1a; CSV 代表逗号分隔值&#xff08;comma-separated values&#xff09;&#xff0c;CSV 文件就是使用逗号分隔数据的文本文件。 一个 CSV 文件包含一行或多行数据&#xff0c;每一…...

15.消息队列RabbitMQ

一、基本概念 RabbitMQ 是一个开源的AMQP实现&#xff0c;服务器端用Erlang语言编写&#xff0c;支持多种客户端&#xff0c;如&#xff1a;Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等&#xff0c;支持AJAX。用于在分布式系统中存储转发消息&#xf…...

并发编程之死锁问题介绍

一、本文概览 死锁问题在并发编程中是一个非常致命的问题&#xff0c;问题一旦产生&#xff0c;只能通过重启机器、修改代码来修复问题&#xff0c;下面我们通过一小段文章内容介绍下死锁以及如何死锁的预防 二、什么是死锁&#xff1f; 在介绍死锁之前&#xff0c;先来明确下什…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式 文章目录 设计模式一、socket.h 接口&#xff08;interface&#xff09;二、socket.cpp 实现&#xff08;implementation&#xff09;三、server.cpp 使用封装&#xff08;main 函数&#xff09;四、client.cpp 使用封装&#xff08;main 函数&#xff09;五、退出方法…...