长连接技术
个人学习记录,欢迎指正
1.轮询
1.1 轮询的形式
短连接轮询
前端每隔一段时间向服务端发起一次Http请求来获取数据。
const shortPolling = () => { const intervalHandler = setInterval(() => {fetch('/xxx/yyy').then(response => response.json()).then(response => {/* 自定义短轮询成功标记 */if(response?.code === '1') {/* 自定义工作代码 *//* 结束短轮询 */ clearInterval(intervalHandler) } }) }, 5000); }长连接轮询
前端向服务端发起一次Http请求,当接收到响应体时重新发起请求来获取数据。
const longPolling = () => {fetch('/xxx/yyy').then(response => response.json()).then(data => {/* 自定义工作代码 *//* 继续长轮询 */longPolling();}) }
1.2 轮询的实现
基于Ajax技术轮询
在1中已经举了关于基于ajax技术实现长轮询和短轮询的例子
基于Iframe的轮询
古老的轮询方式,需要装填数据到jsp,php等形式文档中,没有实现前后端分离开发。
插入: 前端在页面中插入一个隐藏的iframe,iframe的src设置为后端接口地址。
填充: 接口返回数据格式为html,服务端用传统web开发形式向html中插入数据,例如php,jsp。
通信: 返回的html在iframe中运行,通过postMessage与原页面进行通信。
轮询: 原页面收到数据后重新加载iframe进行下次轮询(可以根据策略进行长轮询或短轮询)。
基于Jsonp的轮询
古老的轮询方式,请求失败时无法通过删除标签关闭连接。
插入: 前端在页面中插入一个script标签,src设置为后端接口地址,参数上拼接回调函数名称,当接收到数据后调用之。
填充: 接口返回可执行脚本,脚本最后调用回调函数,便于通知数据已接收到。
通信: 通过回调函数通信。
轮询: 接收到数据后前端重新发起Jsonp轮询,删除标签后插入新的标签继续请求(根据需求进行长轮询或短轮询)。
2.iframe长连接
原理
例如使用http1.x进行通信,服务端在发送响应信息后不关闭信道(在nodejs中即不写
res.end()),每隔一段时间向客户端发送一次消息。这个可以利用服务端持续向iframe输入文档实现。如果使用fetch,xhr,那么无法直接实现,它们只能支持接收一次消息。(目前一般不使用iframe这种古老做法)
前端代码
<html> <head><meta charset="UTF-8" /> </head> <body><div id="display-div"></div><button onclick="handleStartConnect()">开始连接</button><button onclick="handleStopConnect()">断开连接</button><script type="text/javascript">// 开始连接const handleStartConnect = () => {const iframe = document.createElement("iframe");iframe.id = "iframe-connector";iframe.src = "/iframeLongConnection";iframe.style.display = "none";document.body.append(iframe);};// 断开连接const handleStopConnect = () =>document.querySelector("#iframe-connector").remove();// 收集长连接信息 window.addEventListener("message", (event) => {document.querySelector("#display-div").innerHTML = event.data;});</script> </body> </html>服务器代码
let fs = require("fs");// 服务器基本服务 const read = (path, res) => { // 支持读取html和js fs.readFile(path, (err, data) => {if (err) console.log(err);else {res.writeHead(200, {"Content-Type":path.slice(-2, path.length) === "js"? "text/javascript": "text/html",});res.write(data);res.end();} }); };// 输入到iframe中的模板 const getTemplate = () => { const template = `<script type="text/javascript">window.parent.postMessage(new Date().toLocaleTimeString(), "http://localhost:3000/index.html");</script> `; return template; };// 服务端定时器维持长连接 const circulate = (res) => { res.writeHead(200, { "Content-Type": "text/html" }); setInterval(() => {res.write(getTemplate()); }, 1000); };require("http") .createServer(function (req, res) {// 处理图标if (req.url === "/favicon.ico") res.end();// 长连接测试else if (req.url === "/iframeLongConnection") circulate(res);// 服务器基本服务else read("." + req.url, res); }) .listen(3000, function (err) {if (err) console.log(err);else console.log("运行成功"); });
4.Websocket长连接
4.1 Websocket实现
4.1 综述
技术综述:
websocket是协议,是对http协议的升级。
websocket基于TCP协议,也是使用80端口。
功能特点:
- 前端实现简单,只需要建立连接,监听屈指可数的几个事件。
- 支持全双工通信。服务端和客户端可以互相发送消息。
- 不局限于web端。其它终端设备或应用程序也可以使用该协议。
4.2 web端Websocket事件和方法
事件 描述 open 连接建立 close 连接关闭 error 发生错误 message 接收信息
实例方法 描述 send 发送消息 close 关闭连接 4.3 服务端Websocket的事件和方法
服务端实现websocket通常采用第三方库,不同的第三方库对方法和事件的规定各不相同,在此不做具体介绍。
4.4 客户端代码实现
<html> <head><meta charset="UTF-8" /> </head> <body><button onclick="handleBuild()">建立连接</button><button onclick="socket.close()">断开连接</button><button onclick="socket.send(123)">发送一条消息</button><script type="text/javascript">let socket = null;// 连接相关事件监听函数const handleMessage = (event) => alert(event.data);const handleOpen = () => alert("连接成功");const handleError = () => alert("连接错误");const handleClose = () => {alert("连接关闭");socket.removeEventListener("open", handleOpen);socket.removeEventListener("close", handleClose);socket.removeEventListener("error", handleError);socket.removeEventListener("message", handleMessage);};// 建立连接const handleBuild = () => {socket = new WebSocket("ws://localhost:3001/testSocket");socket.addEventListener("open", handleOpen);socket.addEventListener("close", handleClose);socket.addEventListener("error", handleError);socket.addEventListener("message", handleMessage);};// 关闭连接const handleDestroy = () => socket.close();// 发送消息const sendMessage = (message) => socket.send(JSON.stringify(message));</script> </body> </html>4.5 服务端代码实现
const fs = require("fs"); const ws = require("nodejs-websocket");// 基本读写服务 const read = (path, res) => {// 支持读取html和jsfs.readFile(path, (err, data) => {if (err) console.log(err);else {res.writeHead(200, {"Content-Type":path.slice(-2, path.length) === "js"? "text/javascript": "text/html",});res.write(data);res.end();}}); };require("http").createServer(function (req, res) {// 处理图标if (req.url === "/favicon.ico") res.end();else read("." + req.url, res);}).listen(3000, function (err) {if (err) console.log(err);else console.log("运行成功");});const wsServer = ws.createServer((conn) => {// 接收信息conn.on("text", (text) =>conn.sendText(`服务端已收到信息,您的信息是${text}`));// 连接错误conn.on("error", () => console.log("连接错误"));// 连接关闭conn.on("close", () => console.log("连接断开")); });wsServer.on("connection", () => console.log("新连接建立")); wsServer.listen(3001);
4.2 Websocket建立与销毁
Http握手
Websocket连接建立需要Http1.1或以上版本的get方法握手,这个过程在浏览器调试栏中无法抓包得到,只能抓包分析Websocket协议。
在前端和后端实现websocket时这个过程和配置对于开发者是无感知的。
请求头:
字段 取值 含义 是否必设置 Connection upgrade 希望协议升级 必须 Upgrade websocket 协议应该升级到websocket协议 必须 Sec-Websocket-Key 经过base64编码的16字节随机值 必须 Sec-WebSocket-Version 版本值 websocket版本 必须 Sec-WebSocket-Protocol 子协议名称 websocket通信时需要的子协议 非必须 Sec-WebSocket-Extensions 扩展协议名称 websocket通信时的扩展协议 非必须 响应头:
字段 取值 含义 是否必设置 Sec-WebSocket-Accept SHA-1哈希值 是否支持websocket协议 必须 Sec-WebSocket-Version websocket版本 选择支持的websocket版本 必须 Sec-WebSocket-Protocol 子协议名称 选择支持的子协议 非必须 Sec-WebSocket-Extensions 扩展协议名称 选择支持的扩展协议名称 非必须 响应状态码:
响应状态码为101时表示可以使用websocket协议
Sec-Websocket-Key验证:
验证过程类似于加密解密。 客户端传给服务端Sec-Websocket-Key,服务端将这个key和一个规定的并且是固定的Websocket魔数(字符串)拼接。之后服务端将这个拼接的字符串输入SHA-1哈希算法,得到哈希值。最后服务端将哈希值返回给客户端,客户端用同样方式解密来判断服务端是否支持websocket协议。
挥手
服务端发出关闭连接的消息或客户端发来关闭连接的消息后将关闭websocket连接
5.SSE长连接
5.1 综述
技术综述:
SSE是一种基于Http协议的技术,不是一种新的协议。
功能特点:
- 前端需要实现代码不多。
- 由于只是使用Http协议,因此前后端的配置会比使用Websocket协议简单些。
- 由于只是使用Http协议,因此只能服务端向前端推送消息,相比Websocket协议的长连接像阉割版。
性能限制:
同一个浏览器同一个域的Http连接最多支持并发6个,如果长时间用SSE技术保持长连接,会降低该域的并发连接数量。
5.2 客户端代码实现
<html><head><meta charset="UTF-8" /></head><body><div id="message-collector"></div><button onclick="handleBuild()">建立连接</button><button onclick="SSETarget.close()">关闭连接</button><script type="text/javascript">let SSETarget = null;const handleBuild = () => {SSETarget = new EventSource("http://localhost:3002/sseStream");SSETarget.addEventListener("open", () => alert("数据链路可以通信"));SSETarget.addEventListener("error", () => alert("数据链路发生错误"));// 接收数据SSETarget.addEventListener("message",(event) =>(document.querySelector("#message-collector").innerHTML =event.data));// 监听服务端配置的自定义事件SSETarget.addEventListener("testEvent", (event) => console.log(event));};</script></body> </html>5.3 服务端代码实现
- 响应类型: 保证返回的数据类型是
text/event-stream。- 响应数据结构: 保证换行返回,保证数据是
xxx: yyy形式返回,xxx可取值有event, data, id等等,分别表示描述事件的响应,描述数据内容的响应,描述数据id的响应。// 服务器基本读写服务 const read = (path, res) => {// 支持读取html和jsrequire("fs").readFile(path, (err, data) => {if (err) console.log(err);else {res.writeHead(200, {"Content-Type":path.slice(-2, path.length) === "js"? "text/javascript": "text/html",});res.write(data);res.end();}}); };require("http").createServer((req, res) => {// SSE技术服务端简单实现if (req.url === "/sseStream") {res.writeHead(200, {// 必须得返回类型"Content-Type": "text/event-stream"});res.write("retry: 10000\n");// 自定义一个事件res.write("event: testEvent\n");// 在该自定义事件下发送信息给客户端res.write("id: " + "testId\n\n");res.write("data: " + new Date() + "\n\n");interval = setInterval(() => {res.write("event: message\n");res.write("id: " + "messageId\n\n");res.write("data: " + new Date() + "\n\n");}, 1000);req.connection.addListener("close", () => clearInterval(interval), false);} // 处理图标else if (req.url === "/favicon.ico") res.end();// 服务器基本服务else read("." + req.url, res);}).listen(3002);
相关文章:
长连接技术
个人学习记录,欢迎指正 1.轮询 1.1 轮询的形式 短连接轮询 前端每隔一段时间向服务端发起一次Http请求来获取数据。 const shortPolling () > { const intervalHandler setInterval(() > {fetch(/xxx/yyy).then(response > response.json()).then(respo…...
供电系统分类详解
一、供电系统分类 电力供电系统一般有5种供电模式,常用的有:IT系统,TT系统,TN系统,其中TN系统又可以分为TN-C,TN-S,TN-C-S。 1、TN-C系统(三相四线制) 优点: 该系统中…...
基于centos7的k8s最新版v1.29.2安装教程
k8s概述 Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。 Kubernetes 这个名字源于希腊语&…...
【赠书第20期】AI绘画与修图实战:Photoshop+Firefly从入门到精通
文章目录 前言 1 入门篇:初识Photoshop与Firefly 2 进阶篇:掌握Photoshop与Firefly的核心技巧 3 实战篇:运用Photoshop与Firefly进行创作 4 精通篇:提升创作水平,拓展应用领域 5 结语 6 推荐图书 7 粉丝福利 前…...
如何在并行超算云上玩转PWmat③:使用Q-Flow提交计算的案例演示
3月的每周二下午14:00我们将会在并行直播间为大家持续带来线上讲座。前面两期我们分享了”PWmat特色功能和应用“以及“如何在并行超算云平台使用PWmat计算软件”主题讲座,回看视频和PPT已上传至B站”龙讯旷腾“账号内。 本周张持讲师将继续带着大家手把手上机教学…...
html5cssjs代码 017样式示例
html5&css&js代码 017样式示例 一、代码二、解释 这段HTML代码定义了一个网页的基本结构,包括头部、主体和尾部。在头部中,设置了网页标题、字符编码和样式。主体部分包含一个标题和一个表格,表格内分为两个单元格,左侧为…...
Vue.js动画
Vue.js动画 Vue.js动画是指在Vue组件中通过添加/移除CSS类或应用CSS过渡/动画效果来实现的视觉效果。这些动画可以帮助改善用户体验,使界面更加生动和吸引人。 Vue.js提供了两种类型的动画:过渡和动画。 过渡:过渡是在元素插入、更新或删除…...
信号与系统学习笔记——信号的分类
目录 一、确定与随机 二、连续与离散 三、周期与非周期 判断是否为周期函数 离散信号的周期 结论 四、能量与功率 定义 结论 五、因果与反因果 六、阶跃函数 定义 性质 七、冲激函数 定义 重要关系 作用 一、确定与随机 确定信号:可以确定时间函数…...
PyTorch深度学习实战(39)——小样本学习
PyTorch深度学习实战(39)——小样本学习 0. 前言1. 小样本学习简介2. 孪生网络2.1 模型分析2.2 数据集分析2.3 构建孪生网络 3. 原型网络3. 关系网络小结系列链接 0. 前言 小样本学习 (Few-shot Learning) 旨在解决在训练集中只有很少样本的情况下进行分…...
论文阅读——Vision Transformer with Deformable Attention
Vision Transformer with Deformable Attention 多头自注意力公式化为: 第l层transformer模块公式化为: 在Transformer模型中简单地实现DCN是一个non-trivial的问题。在DCN中,特征图上的每个元素都单独学习其偏移,其中HWC特征图上…...
AJAX概念和axios使用、URL、请求方法和数据提交、HTTP协议、接口、form-serialize插件
AJAX概念和axios使用 AJAX概念 AJAX就是使用XMLHttpRequest对象与服务器通信,它可以使用JSON、XML、HTML和text文本等格式发送和接收数据,AJAX最吸引人的就是它的异步特性,也就是说它可以在不重新刷新页面的情况下与服务器通信,…...
【R语言基础操作】
🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一|统计学|干货分享 擅长Python、Matlab、R等主流编程软件 累计十余项国家级比赛奖项,参与研究经费10w、40w级横向 文…...
sqlite 常见命令 表结构
在 SQLite 中,将表结构保存为 SQL 具有一定的便捷性和重要性,原因如下 便捷性: 备份和恢复:将表结构保存为 SQL 可以方便地进行备份。如果需要还原或迁移数据库,只需执行保存的 SQL 脚本,就可以重新创建表…...
基于深度学习的车辆检测技术
基于深度学习的车辆检测技术是现代智能交通系统的重要组成部分,它利用计算机视觉和机器学习算法,特别是深度学习模型,来识别和定位图像或视频中的车辆。这项技术广泛应用于自动驾驶、交通监控、违章抓拍等多个领域。 深度学习车辆检测技术的…...
MyBatis 之三:配置文件详解和 Mapper 接口方式
配置文件 MyBatis 的配置文件是 XML 格式的,它定义了 MyBatis 运行时的核心行为和设置。默认的配置文件名称为 mybatis-config.xml,该文件用于配置数据库连接、事务管理器、数据源、类型别名、映射器(mapper 文件)以及其他全局属性…...
【PyTorch】基础学习:一文详细介绍 torch.load() 的用法和应用
【PyTorch】基础学习:一文详细介绍 torch.load() 的用法和应用 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程ὄ…...
事务、并发、锁机制的实现
配置全局事务 DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: mydb,USER:root,PASSWORD:pass,HOST:127.0.0.1,PORT:3306,ATOMIC_REQUESTS: True, # 全局开启事务,绑定的是http请求响应整个过程# (non_atomic_requests可局部实现不让事务控制)} } …...
PC-DARTS: PARTIAL CHANNEL CONNECTIONS FOR MEMORY-EFFICIENT ARCHITECTURE SEARCH
PC-DARTS:用于内存高效架构搜索的部分通道连接 论文链接:https://arxiv.org/abs/1907.05737 项目链接:https://github.com/yuhuixu1993/PC-DARTS ABSTRACT 可微分体系结构搜索(DARTS)在寻找有效的网络体系结构方面提供了一种快速的解决方案…...
git的下载与安装
下载 首先,打开您的浏览器,并输入Git的官方网站地址 点击图标进行下载 下载页面会列出不同操作系统和平台的Git安装包。根据您的操作系统(Windows、macOS、Linux等)和位数(32位或64位),选择适…...
windows文档格式转换的实用工具
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...


