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

Web实时通信的学习之旅:WebSocket入门指南及示例演示

文章目录

    • WebSocket的特点
        • 1、工作原理
        • 2、特点
        • 3、WebSocket 协议介绍
        • 4、安全性
    • WebSocket的使用
      • 一、服务端
        • 1、创建实例:创建一个webScoket实例对象
          • 1.1、WebSocket.Server(options[,callback])方法中options对象所支持的参数
          • 1.2、同样也有一个加密的 wss:// 协议。类似于 WebSocket 中的 HTTPS。
        • 2、监听连接:ws通过connection事件来监听连接
        • 3、发送数据:ws通过send()方法来发送数据
        • 4、接收数据:ws通过message事件来接收数据
        • 5、关闭WebSocket服务器:通过监听close事件关闭服务器
      • 二、客户端
        • 1、客户端实现WebScoket连接
        • 2、WebScoket的重连机制
        • 3、WebScoket的心跳保活
        • 4、客户端主动断开连接
        • 5、WebScoket添加token的几种方法
          • 5.1、使用send发送参数
          • 5.2、请求地址中携带参数
          • 5.3、基于协议头
      • 三、入门例子
        • 1、服务端
          • 1.1、ws模块:
          • 1.2、安装ws:
          • 1.3、创建WebSocket服务器:
        • 2、客户端
        • 3、运行结果
          • 3.1、服务端输出:
          • 3.2、客户端输出:
    • 总结

WebSocket的出现,使得浏览器具备了实时双向通信的能力。且它不在需要进行3次握手与4次挥手,只需要在客户端创建一个socket实例并且提供它所要连接服务端的IP地址和端口,而服务端创建另一个socket并绑定本地端口进行监听,然后客户端进行连接服务端,服务端接受连接之后双方建立了一个端对端的TCP连接,在该连接上就实现双向通讯了。本文由浅入深,介绍了WebSocket如何建立连接、交换数据的细节,以及数据帧的格式。此外,还简要介绍了针对WebSocket的安全攻击,以及协议是如何抵御类似攻击的。

WebSocket的特点

1、工作原理

浏览器发出webSocket的连线请求,服务器发出响应,这个过程称为握手,握手的过程只需要一次,就可以实现持久连接。

WebSocket 的工作原理如下:

  • 客户端向服务器发送一个 HTTP 请求,请求建立 WebSocket 连接。
  • 服务器收到请求后,会返回一个 HTTP 响应,响应中包含一个 101 Switching Protocols 状态码,表示同意建立 WebSocket 连接。
  • 服务器和客户端通过 TCP 连接进行通信,数据格式为 JSON、二进制或文本。

在这里插入图片描述

2、特点

WebSocket是真正的全双工通信机制,建立连接后客户端与服务器端是完全平等的,可以互相主动请求。而HTTP长连接基于HTTP,是传统的客户端对服务器发起请求的模式。 HTTP长连接中,每次数据交换除了真正的数据部分外,服务器和客户端还要大量交换HTTP header,消息交换效率低。Websocket协议通过第一个request建立了TCP连接之后,之后交换的数据都不需要发送 HTTP header就能交换数据,这显然和原有的HTTP协议有区别所以它需要对服务器和客户端都进行升级才能实现,当然在现在这个时代,我们的主流浏览器都是支持HTML5的,使用时我们直接使用即可。

  • 实时性:服务器可以主动向客户端发送消息,实现实时通信。
  • 双向通信:客户端和服务器之间可以同时发送和接收数据。
  • 性能:WebSocket 连接建立后,数据传输效率更高,减少了 HTTP 请求的次数。
  • 兼容性:WebSocket 协议在大多数浏览器中得到了支持,无需额外插件。
3、WebSocket 协议介绍
  • WebSocket 协议的底层协议也是TCP协议
  • WebSocket 协议的标识符为ws,加密后为wss
  • WebSocket 协议没有同源限制,即WebSocket 协议可以跨域通信
  • WebSocket 协议是有状态的,是前后端交互的长连接,即建立连接后可以保持连接状态,通信时可以省略部分状态信息
  • WebSocket 协议可以发送文本,同时也可以发送二进制数据
4、安全性

WebSocket 协议本身是安全的,但你需要确保 WebSocket 连接是通过 HTTPS 协议建立的,以防止中间人攻击。在 Node.js 中,你可以使用 wss 模块来创建一个安全的 WebSocket 服务器。

WebSocket的使用

一、服务端

1、创建实例:创建一个webScoket实例对象
 //创建一个WebSocket服务器,在3000端口启动const WebSocket = require('ws')const server = new WebSocket.Server({port:3000})
1.1、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:允许的最大消息大小(以字节为单位)
1.2、同样也有一个加密的 wss:// 协议。类似于 WebSocket 中的 HTTPS。
  • wss:// 协议不仅是被加密的,而且更可靠。

  • 因为 ws:// 数据不是加密的,对于任何中间人来说其数据都是可见的。并且,旧的代理服务器不了解 WebSocket,它们可能会因为看到“奇怪的” header 而中止连接。

  • 另一方面,wss:// 是基于 TLS 的 WebSocket,类似于 HTTPS 是基于 TLS 的 HTTP),传输安全层在发送方对数据进行了加密,在接收方进行解密。因此,数据包是通过代理加密传输的。它们看不到传输的里面的内容,且会让这些数据通过。

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

只要有WebSocket连接到该服务器,就会触发’connection’事件;req对象可以用来获取客户端的信息,如ip、端口号

// 监听连接事件
server.on('connection',function connection(ws,req){const ip = req.socket.remoteAddressconst port = req.socket.remotePortconst clientName = ip + portconsole.log('%s is connected ',clientName)})
3、发送数据:ws通过send()方法来发送数据
 server.on('connection',function connection(ws,req){const ip = req.socket.remoteAddressconst port = req.socket.remotePortconst clientName = ip + port// 发送消息到客户端ws.send('Welcome ' + clientName)})

send(data [,options][,callback])

data:发送的数据
options对象:

  • (1)compress:指定数据是否需要压缩。默认为true
  • (2)binary:指定数据是否通过二进制传送。默认是自动检测
  • (3)mask:指定是否应遮罩数据。
  • (4)fin:指定数据是否为消息的最后一个片段。默认为true
4、接收数据:ws通过message事件来接收数据

当客户端有消息发送给服务器时,服务器就能够触发该消息

server.on('connection',function connection(ws){// 监听接收消息事件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)}})})})
5、关闭WebSocket服务器:通过监听close事件关闭服务器
server.on('close',function close(){console.log('disconnected')
})

二、客户端

创建了一个webScoket实例对象常用属性和方法的介绍

属性说明
url当前连接的webScoket接口地址
readyState当前连接的状态: 0:正在链接中 1:已经链接并且可以通讯 2:连接正在关闭 3;连接已关闭或者没有链接成功
onopen连接成功的回调函数
onerror连接失败的回调函数
onmessage从服务端接受到信息的回调函数
onclose连接关闭的回调函数
binaryType使用二进制的数据类型连接
protocol服务器选择的下属协议
bufferedAmount未发送至服务器的二进制字节数
close()关闭当前连接
send(data)发送消息到服务器
1、客户端实现WebScoket连接
// 创建 WebSocket 连接
const ws = new WebSocket('ws://localhost:3000')// 连接打开时触发
ws.onopen = function () {console.log('我们连接成功啦...')// 发送消息到服务器webSocket.send('Hello!')
}// 连接出错时触发
ws.onerror = function () {console.log('连接失败了...')
}// 接收到服务器消息时触发
ws.onmessage = function (e) {console.log('服务端传来数据啦...' + e.data)
}// 连接关闭时触发
ws.onclose = function () {console.log('连接关闭了...')
}
2、WebScoket的重连机制

当我们正在使用WebScoket的时候,难免会出现WebScoket的断联,这个时候,我们只需要在onclose的回调函数中,重新链接即可

ws.onclose = function (e) {// 1每10秒重连一次,直到连接成功setTimeout(function () {// 重新调用连接webSocket事件ws = new WebSocket('ws://192.168.31.19:8081/')ws.onopen = function () {console.log('连接成功...')} }, 10000);};
3、WebScoket的心跳保活

websocket长连接有默认的超时时间(1分钟),也就是说,超过一定的时间客户端和服务器之间没有发生任何消息传输,连接会自动断开;除此之外,服务器或防火墙一般也会在一段时间不活动并超时之后终止外部的长连接。因此,若需要使客户端一直保持连接,就需要设置心跳保活机制了。

实现原理:我们可以每次在 每次保持心跳保活的时候,向WebScoket发送一条消息,证明我们还"活着"

var timeout = 1000 * 30 //心跳间隔  
var timeoutTimer=null //保持心跳的定时器timeoutTimer = setTimeout(function () {ws.send('HeartBeat')}, timeout)
4、客户端主动断开连接
// 客户端主动断开连接
ws = new WebSocket('ws://192.168.31.19:8081/')
ws.close();
5、WebScoket添加token的几种方法
5.1、使用send发送参数
var  ws = new WebSocket("ws://" + url );
ws.onopen=function(){ws.send(token)
}
5.2、请求地址中携带参数
var  ws = new WebSocket("wss://" + url?token );
5.3、基于协议头

websocket请求头中可以包含Sec-WebSocket-Protocol这个属性,该属性是一个自定义的子协议。它从客户端发送到服务器并返回从服务器到客户端确认子协议。我们可以利用这个属性添加token。

var  ws = new WebSocket("ws://" + url,[token]);

三、入门例子

例子包括了WebSocket服务端、WebSocket客户端。

1、服务端

Node使用ws创建WebSocket服务器

1.1、ws模块:

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

1.2、安装ws:
npm install ws
1.3、创建WebSocket服务器:

启动3000端口。当有新的连接请求到达时,打印日志,然后延迟两次向客户端发送消息。当收到到来自客户端的消息时,同样打印日志。

server.js

var WebSocket = require('ws');var wss = new WebSocket.Server({port: 3000
});// 创建一个TextDecoder实例来处理字符串
const decoder = new TextDecoder('utf-8');wss.on('connection', function connection(ws) {console.log('server: receive connection.');ws.on('message', function incoming(message) {console.log('server: received', decoder.decode(message));});let data1 = {name: 'zhangsan',age: 18}let data2 = {name: 'lisi',age: 19}let data3 = 'wangwu'sendData(ws, data1, 1000 * 60 * 1)sendData(ws, data2, 1000 * 60 * 2)sendData(ws, data3, 1000 * 60 * 3)
});const sendData = (ws, data = '', delay = 1000) => {if (!data) returnif (typeof data === 'object') data = JSON.stringify(data)setTimeout(() => {ws.send(data);}, delay)
}
2、客户端

向3000端口发起WebSocket连接。连接建立后,打印日志,同时向服务端发送消息。接收到来自服务端的消息后,同样打印日志。

app.vue

const ws = new WebSocket('ws://localhost:3000');
ws.onopen = function () {console.log('我们连接成功了');ws.send('hello');
};
ws.onmessage = function (e) {console.log('服务端传来数据了:',e.data);
};
ws.onclose = function () {console.log('连接关闭了');
};
ws.onerror = function (err) {console.log('连接失败了', err);
};
3、运行结果

可分别查看服务端、客户端的日志,这里不展开。

3.1、服务端输出:
server: receive connection.
server: received hello
3.2、客户端输出:
我们连接成功了
服务端传来数据了:{"name":"zhangsan","age":18}
服务端传来数据了:{"name":"lisi","age":19}

总结

WebSocket 是一种强大的网络通信协议,它允许服务器和客户端之间进行实时、双向通信。在 WebSocket 连接中,服务器可以主动向客户端发送消息,这对于实时应用来说非常重要。通过使用 JavaScript 和后端语言,你可以轻松实现 WebSocket 通信。在实际应用中,WebSocket 已被广泛应用于在线聊天、股票交易、游戏等领域。

WebSocket 是一种在浏览器和服务器之间建立持久连接的现代方式。

  • WebSocket 没有跨源限制
  • 浏览器对 WebSocket 支持很好
  • 可以发送/接收字符串和二进制数据

WebSocket 方法:

  • socket.send(data)
  • socket.close([code], [reason])

WebSocket 事件:

  • open
  • message
  • error
  • close

WebSocket 自身并不包含重新连接(reconnection),身份验证(authentication)和很多其他高级机制。因此,有针对于此的客户端/服务端的库,并且也可以手动实现这些功能。

有时为了将 WebSocket 集成到现有项目中,人们将主 HTTP 服务器与 WebSocket 服务器并行运行,并且它们之间共享同一个数据库。对于 WebSocket 请求使用一个通向 WebSocket 服务器的子域 wss://ws.site.com,而 https://site.com 则通向主 HTTP 服务器。

相关文章:

Web实时通信的学习之旅:WebSocket入门指南及示例演示

文章目录 WebSocket的特点1、工作原理2、特点3、WebSocket 协议介绍4、安全性 WebSocket的使用一、服务端1、创建实例:创建一个webScoket实例对象1.1、WebSocket.Server(options[,callback])方法中options对象所支持的参数1.2、同样也有一个加密的 wss:/…...

分治精炼宝库-----快速排序运用(⌯꒪꒫꒪)੭

目录 一.基本概念: 一.颜色分类: 二.排序数组: 三.数组中的第k个最大元素: 解法一:快速选择算法 解法二:简单粗暴优先级队列 四.库存管理Ⅲ: 解法一:快速选择 解法二:简单粗…...

快速修复mfc100u.dll丢失解决方案

相连文章:SecureCRT的安装破解 [详细过程2024] 有小伙伴向我反馈在打开SecureFX注册机之后显示【mfc100u.dll找不到】重装之后也没有用,这个是因为Microsoft Visual C的运行时组件和库出现了错误,直接选择重新安装就可以 出现这种情况的原因…...

【C++深度探索】继承机制详解(一)

hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页:大耳朵土土垚的博客 &#x1…...

力扣第218题“天际线问题”

在本篇文章中,我们将详细解读力扣第218题“天际线问题”。通过学习本篇文章,读者将掌握如何使用扫描线算法和堆来解决这一问题,并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释,以便于理解。 问题描述 力扣第…...

帝国cms未审核文章可视化预览效果

有时候为了让编辑更加清楚的看到别人审核之后的效果,同时文章有需要下一级审核才能在前端展示出来,今天就来展示一个未审核文章预览审核后的效果 这次给某出版社开发的时候,他们需要实现编辑能够预览自己发布之后的审核效果,所以就…...

医院管理系统带万字文档医院预约挂号管理系统基于spingboot和vue的前后端分离java项目java课程设计java毕业设计

文章目录 仓库管理系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档(9.9¥带走) 仓库管理系统 一、项目演示 医院管理系统 二、项目介绍 基于springbootvue的前后端分离医院管…...

爬虫技术在物联网数据采集中的应用

爬虫技术在物联网数据采集中的应用案例主要包括以下几个方面: 电商平台数据采集:例如,使用Python编写的网络爬虫可以用于爬取京东网页相关数据,如品牌、标题、价格、店铺等,并进行数据处理及可视化展示。这种方法不仅可…...

spring boot初始化的几个总结

spring intializr File->New->Project 注意:Spring Initializer中 Java版本选择模块已经不支持1.8了。 Spring Boot 3.x要求 Java最低版本为17, 最新的SpringBoot版本已经要求Java22了 所以,你可以升级Java版本,使用Spri…...

springcloud第4季 seata报could not find any implementation for class

一 问题说明 1.1 描述 在使用seata2.0alibaba-cloud 2022.0.0.0-RC2nacos 2.2.3 模拟下订单分布式事务场景,出现如下问题:java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 查看服务端:java.util.ServiceCo…...

IT之家最新科技热点

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…...

对象实例化过程

目录 一、Java对象实例化在JVM中的过程: 类加载与初始化 分配内存 初始化对象内存 设置对象头 执行初始化方法 构造方法执行 二、对象的创建过程 一、Java对象实例化在JVM中的过程: 类加载与初始化: 当JVM需要实例化一个对象时,它…...

常见漏洞之XSS

一、XSS简介 XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的网络攻击方式,通过在网页中注入恶意脚本,当其他用户浏览这些网页时,这些嵌入的恶意脚本会在其浏览器上执行,从而进行各种恶意…...

Python变量的命名规则与赋值方式

第二章:Python 基础语法 第一节:变量的命名规则与赋值方式 2.1.1 引言 在编程中,变量是存储数据的基本单元。变量的命名和赋值是编程语言中表达和操作数据的基础。了解和遵循变量命名规则对于编写清晰、可维护的代码至关重要。 2.1.2 变量…...

昇思25天学习打卡营第7天|网络构建

昇思25天学习打卡营第7天|网络构建 前言函数式自动微分函数与计算图微分函数与梯度计算Stop GradientAuxiliary data神经网络梯度计算 个人任务打卡(读者请忽略)个人理解与总结 前言 非常感谢华为昇思大模型平台和CSDN邀请体验昇思大模型!从今…...

扩展阅读:什么是中断

如果用一句话概括操作系统的原理,那就是:整个操作系统就是一个中断驱动的死循环,用最简单的代码解释如下: while(true){doNothing(); } 其他所有事情都是由操作系统提前注册的中断机制和其对应的中断处理函数完成的。我们点击一下鼠标,敲击一下键盘,执行一个程序,…...

git 命令学习之branch 和 tag 操作

引言 在项目一个迭代过程结束之时,或是一个版本发布之后,我们要进行 新版本的开发,这时就需要对原来的项目代码进行封存,以及新项目代码的开始,这时就需要用到 branch 和 tag 操作。下面简单说说对这两个操作的理解。…...

如何理解 IEEE 754 单精度浮点型能表示的最小绝对值、最大绝对值

文章目录 解答最小绝对值最大绝对值总结 细节理解1. 为什么非规格化数的指数偏移量为126(而不是127)?规格化数与非规格化数非规格化数的指数偏移量非规格化数的尾数非规格化数的值示例 解答 IEEE 754单精度浮点数使用32位来表示一个数值&…...

LeetCode 算法:二叉树的右视图 c++

原题链接🔗:二叉树的右视图 难度:中等⭐️⭐️ 题目 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4…...

Java 并发编程常见问题

1、线程状态它们之间是如何扭转的? 1、谈谈对于多线程的理解? 1、对于多核CPU,多线程可以提升CPU的利用率; 2、对于多IO操作的程序,多线程可以提升系统的整体性能及吞吐量; 3、使用多线程在一些场景下可…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

线程同步:确保多线程程序的安全与高效!

全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

docker 部署发现spring.profiles.active 问题

报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...

数据分析六部曲?

引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...