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 服务器。

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

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

相关文章

C++ NetworkToHostOrder、HostToNetworkOrder 模板函数

其作用类型&#xff1a;ntohl、htonl、ntohs、htons 函数的作用&#xff0c;因为要考虑兼容 int128、int64 等数据类型。 IPV6 肯定是 int128 了&#xff0c;使用这两个函数可以帮助人们计算IPV6的地址范围等。 template <class T> static T …

在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?

在 Hibernate 中&#xff0c;getCurrentSession 和 openSession 是两种不同的方法来获取 Session 对象&#xff0c;它们之间存在一些关键的区别。 事务管理方式&#xff1a; getCurrentSession&#xff1a;它依赖于当前的事务上下文&#xff0c;通常与 Spring 等框架集成&…

报表-设计器的使用

1、设计器目录结构 报表设计器以压缩包的方式提供&#xff0c;解压后&#xff0c;目录结构如下&#xff1a; 目录说明&#xff1a; 1、jdk-17&#xff1a;压缩包中自带的windows平台下的jdk17 2、lite-report&#xff1a;报表文件和数据源配置文件的保存位置 3、lite-repor…

Spring MVC(三) 参数传递

1 Controller到View的参数传递 在Spring MVC中&#xff0c;把值从Controller传递到View共有5中操作方法&#xff0c;分别是。 使用HttpServletRequest或HttpSession。使用ModelAndView。使用Map集合使用Model使用ModelMap 使用HttpServletRequest或HttpSession传值 使用HttpSe…

在AI大模型中全精度和半精度参数是什么意思?

环境&#xff1a; 大模型中 问题描述&#xff1a; 在AI大模型中全精度和半精度参数是什么意思&#xff1f; 解决方案&#xff1a; 在深度学习和高性能计算领域&#xff0c;"全精度"和"半精度"通常指的是模型中使用的数值表示的精度&#xff0c;具体涉…

hadoop学习---基于Sqoop的文件导入导出操作

在本地数据库创建数据库表&#xff1a; create database sqoop_test default character set utf8; use sqoop_test; CREATE TABLE emp ( EMPNO int(4) NOT NULL, ENAME varchar(10), JOB varchar(9), MGR int(4), HIREDATE date, SAL int(7), COMM int(7), DEPTNO int(2), PRI…

eslint关闭的方法总结

package.json关闭eslint 直接注释package.json文件中eslint的配置 "eslintConfig": {"root": true,此项是用来告诉eslint找当前配置文件不能往父级查找"env": {"node": true//此项指定环境的全局变量&#xff0c;下面的配置指定为nod…

Mysql实现双机bin-log热备份

在执行前务必停止对主服务器的mysql数据写入&#xff01;&#xff01;&#xff01; 1.修改主机/etc/my.cnf配置,在mysqld下增加配置&#xff1a; log-bin mysql-bin server-id 1 2.获取MASTER_LOG_FILE、MASTER_LOG_POS信息 登录主机mysql&#xff0c;执行&#xff1a; …

【python基础】python经典题目100题

文章目录 前言初阶题目1.字符串2.列表3.元组4.字典5.运算6.random 模块7.open函数8.time模块时间9.其他 进阶题目 前言 本文主要是python经典题目100题&#xff0c;适合入门的新手。仅作自己学习的记录。 初阶题目 1.字符串 题目1&#xff1a;怎么找出序列中的最⼤最⼩值&am…

STM32使用ESP01S连接阿里云物联网平台

一、ESP01S烧录MQTT固件准备 首先准备好烧录工具&#xff0c;可以从官网上进行下载。 MQTT固件官网网址&#xff1a;AT固件汇总 | 安信可科技 (ai-thinker.com) 进去后如下图界面&#xff0c;向下翻找找到MQTT固件&#xff08;1471&#xff09;下载固件即可。 烧录工具光网地…

windows连接CentOS数据库或Tomcat报错,IP通的,端口正常监听

错误信息 数据库错误&#xff1a; ERROR 2003 (HY000): Cant connect to MySQL server on x.x.x.x (10060) Tomcat访问错误&#xff1a; 响应时间过长 ERR_CONNECTION_TIMED_OUT 基础排查工作 【以下以3306端口为例&#xff0c;对于8080端口来说操作是一样的&#xff0c;只需…

【java毕业设计】基于Spring Boot+vue的网上商城购物系统设计与实现(程序源码)-网上商城购物系统

基于Spring BootVue的网上商城购物系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于Spring BootVue的网上商城购物系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及论文的获取方…

Oracle闪回数据库【Oracle闪回技术】(二)

理解Oracle闪回级别【Oracle闪回技术】(一)-CSDN博客 Oracle默认是不开启闪回数据库的。如果开启闪回数据库的前提条件是,开启Oracle归档模式并启用闪回恢复区。 因为闪回日志文件存放在闪回恢复区中,如果在RAC环境下,必须将闪回恢复区存储在集群文件或者ASM文件中。 一…

揭秘APP广告变现:轻松赚取额外收入!

在移动应用&#xff08;APP&#xff09;的世界中&#xff0c;变现能力是衡量一个应用成功与否的关键指标之一。无论是个人开发者还是企业团队&#xff0c;如何通过应用创造收入&#xff0c;始终是一个备受关注的话题。今天&#xff0c;我们将深入探讨APP广告变现的路径&#xf…

使用nmcli命令在各Linux系统上统一的配置网络

前言&#xff1a;原文在我的博客网站中&#xff0c;持续更新数通、系统方面的知识&#xff0c;欢迎来访&#xff01; 使用nmcli命令在各Linux系统上统一的配置网络https://myweb.myskillstree.cn/123.html 你是否会遇到在不同的Linux系统中配置网络时&#xff0c;修改的配置文…

Element UI 表单验证详解与实践

Element UI 作为一款流行的Vue.js UI框架&#xff0c;提供了丰富的表单组件和强大的表单验证功能&#xff0c;极大地简化了前端开发中的表单处理流程。本文将深入探讨Element UI的表单验证机制&#xff0c;包括基本的验证规则、自定义验证规则、以及一些高级应用场景&#xff0…

C语言初阶(6) - 指针

目录 1.指针是什么&#xff1f; 2. 指针和指针类型 2.1 指针 - 整数 2.2 指针的解引用 3. 野指针 3.1 野指针成因 3.2 如何规避野指针 4. 常量指针和指针常量 (const) 4.1.常量指针 4.2.指针常量 5. 指针运算 5.1 指针-整数 5.2 指针-指针 5.3指针的关系运算 6.…

[openwrt-21.02]MT7981+MT7976 WiFi debug指令

openwrt版本信息 NAME="OpenWrt" VERSION="21.02-SNAPSHOT" ID="openwrt" ID_LIKE="lede openwrt" PRETTY_NAME="OpenWrt 21.02-SNAPSHOT" VERSION_ID="21.02-snapshot" HOME_URL="https://openwrt.org/&qu…

【Python】selenium爬虫常见用法和配置,以及常见错误和解决方法

欢迎来到《小5讲堂》 这是《Python》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言无执行文件代码报错信息错误路径手动下载自动下载 选项配置Ch…