客户端与服务端实时通讯(轮询、websocket、SSE)

news2024/11/19 4:26:58

客户端与服务端实时通讯

背景

在某些项目中,某些数据需要展示最新的,实时的,这时候就需要和服务端进行长时间通讯

方案

对于数据实时获取,我们一般会有4种方案:

1.短轮询:使用浏览器的定时器发起http请求,每隔一段时间就请求一次
2.长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
3.websocket:客户端与服务端建立websocket连接,搭建双工(双向)通道
4.SSE(Server-Sent Events):基于HTTP的html5新特性,服务器推送,属于半双工通信模型

轮询

轮询是指客户端定时向服务器发送ajax请求,服务器接到请求后马上返回响应信息并关闭连接。

轮询分为短轮询和长轮询

短轮询

实现原理: 短轮询指客户端每间隔一段时间向服务端发起请求,保持数据的同步。

优点: 可实现基础(指间隔时间较短)的数据更新。

缺点: 这种方法也只是尽量的模拟即时传输,但并非真正意义上的即时通讯,坏处是间隔设置的太长用户体验不好,设置间隔太短后端服务会进行大量的无效查询并且数据没有及时返回前端展示给用户。

长轮询

实现原理: 客户端发送请求后,如果没有数据返回,服务端会将请求放入队列一直连接处理其他请求,直到有数据才返回给客户端,然后客户端再次发起请求,以此轮询。在 HTTP1.0 中客户端可以设置请求头 Connection:keep-alive,服务端收到该请求头之后知道这是一个长连接,在响应报文头中也添加 Connection:keep-alive。客户端收到之后表示长连接建立完成,可以继续发送其他的请求。在 HTTP1.1 中默认使用了 Connection:keep-alive 长连接。
优点: 减少了大量无效的查询,保证每次请求都有数据返回,不会一直占用线程。
缺点: 如果新数据频繁,会进行大量的连接建立和关闭,对服务器的处理能力要求较高。服务器一直保持连接会消耗资源,需要同时维护多个线程,服务器所能承载的 TCP 连接数是有上限的,这种轮询很容易把连接数顶满。每次通讯都需要客户端发起,服务端不能主动推送。

websocket

实现原理: Websocket 实现了客户端与服务端的双向(双工)通信,只需要连接一次,就可以相互传输数据,很适合实时通讯、数据实时更新等场景。
优点:
1.双向通讯:客户端服务端双方都可以主动发起通讯
2.没有同源限制:相对于tcp请求websocket客户端可以与任意服务端通讯,不存在跨域的情况
3.数据量轻:只需要第一次连接时携带请求头,后面的数据通讯都不需要携带请求头
4.传输效率高,因为只需要一次连接
缺点:
1.长连接需要后端处理业务的代码更稳定,推送消息相对复杂
2.长连接对网络要求比较大,需要处理好重连接
3.兼容性差,Websocket只支持IE10及以上

使用

1.客户端代码

  <script>
    let socket = new WebSocket('ws://localhost:8888')
    socket.onopen = function () {
      console.log('1. 客户端连接上了服务器',new Date().getTime());
      socket.send('3. 你好')
    }
    socket.onmessage = function (e) {
      console.log('6',e.data);
    }
</script>

2.服务端代码

let express = require('express')
let app = express()
app.use(express.static(__dirname))
 
 
app.listen(3000)
 
let WebSocket = require('ws')
let wss = new WebSocket.Server({port:8888})
wss.on('connection',function(ws){
  console.log('2.服务器监听到了客户端的连接',new Date().getTime());
  ws.on('message',function(data){
    console.log('4.客户端发来的消息',data);
    ws.send('5.服务端说:你也好')
  })
})

SSE(EventSource)

实现原理: 客户端首先向服务器发送一个 HTTP 请求,然后服务器设置响应头并保持这个连接打开,并周期性地通过这个连接向客户端发送数据。每个数据块都是一个独立的消息。

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

优点:
1.简单易用:只需要在客户端创建一个EventSource对象,指定服务器端的URL,即可进行监听并展示事件。
2.网络带宽节省:EventSource采用长连接的方式进行数据传输,相比于普通的轮询方式,能够节省大量的网络带宽。
3.跨域支持:允许在跨域环境下进行通信,通过适当的响应头授权来自不同域的客户端连接。
缺点:
1.单项通信:只支持服务器向客户端的单向通信,无法实现客户端向服务器的实时交互。
2.不能重连:如果网络连接不稳定,或者服务器端关闭EventStream连接,客户端需要重新连接才能继续监听事件。
3.不支持二进制数据传输:只能传输文本数据,不能传输二进制数据,这在某些场景下可能存在一定的局限性。

使用

1.客户端

var eventSource = new EventSource("/clock");
eventSource.onmessage = function(event) {
  console.log("Received event: " + event.data);
};

2.服务端

let express = require('express')
let app = express()
app.use(express.static(__dirname))
 
let counter = 0
app.get('/clock',function(req,res){
  res.header('Content-Type','text/event-stream')
  let $timer = setInterval(() => {
    // 第一种写法
    res.write(`id:${counter++}\nevent:message\ndata:${new Date().toLocaleString()}\n\n`)
    
    // 另一种写法
    res.write(`event:yya\n`)     // 触发 自定义事件
    res.write(`data:${counter}\n\n`)
  }, 1000 );
 
 
  res.on('close',function(){
    counter = 0
    clearInterval($timer)
  })
})
app.listen(3000)

chatGPT就是使用的这种方式
请添加图片描述
响应头
在这里插入图片描述
响应的数据
在这里插入图片描述

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

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

相关文章

三叠云督察督办解决方案:助力企业高效决策与执行

信息时代的到来&#xff0c;企业面临着日益增长的管理挑战。高竞争的商业环境中&#xff0c;如何实现高效的决策和执行成为了企业迫切需要解决的问题。在现代企业管理中&#xff0c;督察督办工作的重要性也日益凸显。 然而&#xff0c;传统的督察督办模式存在诸多问题&#xff…

JavaScript组合模式

JavaScript组合模式 1 什么是组合模式2 宏命令3 示例&#xff1a;扫描文件夹4 引用父对象 1 什么是组合模式 组合模式是一种结构型设计模式&#xff0c;用于将对象组合成树形结构&#xff0c;并使客户端能够统一处理单个对象和组合对象。它通过使用继承和组合两个概念&#xf…

题目描述:输入数字,第一行为数组的大小,第二行为数组的值。求其中相邻两个数字相差不大于8的最大片段的长度。

题目描述&#xff1a; 输入数字&#xff0c;第一行为数组的大小&#xff0c;第二行为数组的值。求其中相邻两个数字相差不大于8的最大片段的长度。 示例1&#xff1a; 输入&#xff1a;91 2 4 6 12 2 8 6 4 输出&#xff1a;5示例2&#xff1a; 输入&#xff1a;101 4 5 6 2…

数据清洗(1)--数据查缺补漏

前言 之前使用scikit 进行一些基础模型的选择&#xff08;SVM支持向量机&#xff0c;LR算法&#xff0c;KNN&#xff0c;SGD&#xff0c;Bays贝叶斯&#xff0c;决策树&#xff0c;随机森林&#xff09;&#xff0c;创建&#xff0c;训练&#xff08;测试集验证集&#xff09;…

Redis测试新手入门教程

在测试过程中&#xff0c;我们或多或少会接触到Redis&#xff0c;今天就把在小破站看到的三丰老师课程&#xff0c;把笔记整理了下&#xff0c;用来备忘&#xff0c;也希望能给大家带来亿点点收获。 主要分为两个部分&#xff1a; 一、缓存技术在后端架构中是如何应用的&#…

C语言实现求某班学生的平均成绩和均方差

完整代码&#xff1a; /* 已知求成绩的平均值和均方差公式为&#xff1a;&#x1d44e;&#x1d463;&#x1d452; ∑&#x1d460;&#x1d456;/n , &#x1d451;&#x1d452;&#x1d463; √(∑ (&#x1d460;&#x1d456;−&#x1d44e;&#x1d463;&#x1d45…

Android开发知识学习——HTTPS

文章目录 定义HTTPS连接HTTPS 连接建立的过程课后题 定义 HTTP Secure / HTTP over SSL / HTTP over TLS SSL&#xff1a;Secure Socket Layer -> TLS Transport Layer Security 定义&#xff1a;在HTTP之下增加的一个安全层&#xff0c;用于保障HTTP的加密传输 本质&…

Python 自动化测试全攻略:五种自动化测试模型实战详解!

随着移动互联网的发展&#xff0c;软件研发模型逐步完善&#xff0c;软件交付质量越来越受到软件公司的重视&#xff0c;软件测试技术特别是自动化测试技术开始在软件系统研发过程中发挥着越来越重要的作用。 与传统的手工测试技术相比&#xff0c;自动化测试具备了良好的可操…

Mysql进阶-索引篇(下)

SQL性能分析 SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令&#xff0c;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次&#xff0c;通过sql语句的访问频次&#xff0c;我们可…

技术视角下的跑腿小程序开发:关键挑战和解决方案

跑腿小程序作为连接服务提供者和用户的桥梁&#xff0c;面临着诸多技术挑战。本文将聚焦于技术层面的关键挑战&#xff0c;并提供解决方案&#xff0c;以帮助开发者应对技术上的复杂问题。 1. 实时性与性能挑战 挑战&#xff1a; 跑腿小程序需要实时地匹配订单、更新状态和提…

【java学习—十】操作集合的工具类Collections(8)

文章目录 1. 操作集合的工具类&#xff1a; Collections2. 应用3. 查找、替换3.1. max 与 min3.2. 根据Comparator返回max(min) 3.3. frequency 与 replaceAll4. 同步控制 1. 操作集合的工具类&#xff1a; Collections Collections 是一个操作 Set 、List 和 Map 等集合的工具…

从LLM到AIGC,开启AI时代寻宝之旅!

引言 还记得《头号玩家》中男主人公赢得游戏的方式吗——在游戏中漫无目的地闲逛&#xff0c;然后发现彩蛋&#xff0c;获得胜利。 在人工智能领域&#xff0c;有一种新奇性搜索原则的实验&#xff0c;使得机器研究的成功之路恰似寻找彩蛋的道路。比如在不设定“出门”目标的情…

为什么会被【禅道】工具的公司踢出QQ群的反思…………

周末备份Gitlab的代码库&#xff0c;把Gitlab更新到了最新的16.5。顺带看了禅道官网出了最新版本18.8。但是禅道的升级更新并不顺利…………。 先说一下为什么用禅道这个工具&#xff1a; 再使用禅道这个工具前&#xff0c;使用过的工具有QC(Quality Center)、jira&#xff0…

测试工程师简历编写攻略:打造高点击率的简历!

简历是入职职场的一张名片&#xff0c;也是进入职场一块“敲门砖”。从某种角度说&#xff0c;简历也是一张专业人员的说明书。 软件测试人员作为IT行业具有技术含量的职业&#xff0c;一份优秀的简历包含的内容以及如何写好简历尤为重要。接下来从以下两方面来介绍这个话题&a…

Android任务栈和启动模式

Andrcid中的任务栈是一种用来存放Activity实倒的容器。任务最大的特点就是先进后出&#xff0c;它主要有两个基本操作&#xff0c;分别是压栈和出栈。通常Andaid应用程序都有一个任务栈&#xff0c;每打开一个Activity时&#xff0c;该Activity就会被压入任务栈。每销毁一个Act…

eclipse Occurrence

eclipse Occurrence Occurrence of initUi2_setData_99 Window->Preferences->General->Editors->Text Editors->Annotations->Occurrences 个人感觉最好用的颜色&#xff1b; 边线&#xff0c;正文都可以看得清楚

Elasticsearch(一)---介绍

简介 Elasticsearch是一个基于Lucene的实际的分布式搜索和分析引擎。设计用于云计算中&#xff0c;能够达到近实时搜索&#xff0c;稳定&#xff0c;可靠&#xff0c;快速&#xff0c;安装使用方便。基于RESTful接口。 官网地址&#xff1a;Elasticsearch 平台 — 大规模查找…

开关电源测试方案分享:电源纹波及噪声测试方法、测试标准

纹波及噪声影响着设备的性能和稳定性&#xff0c;是开关电源测试的重要环节。通过电源纹波噪声测试&#xff0c;检测电源纹波情况&#xff0c;从而提升开关电源的性能。纳米软件开关电源自动化测试软件助力纹波和噪声测试&#xff0c;提升测试效能。 开关电源纹波及噪声测试方法…

一文分享提升嵌入式代码的分析工具

当前标准的C语言编译器存在普遍只能找出代码中潜在的缺陷&#xff0c;而对程序方案设计并没有效。 使用静态代码分析器有助于提升固件和捕获编译器难以察觉的问题。 1、用于嵌入式的常见代码静态分析工具 代码静态分析工具&#xff0c;顾名思义就是对代码进行静待分析&#…

【Python图像处理局部放大】输入图像,选择两处不同的区域进行放大操作,然后将原始图像、处理后的两个区域以及标记合成新图像进行展示

NeRF-w 渲染后的图像效果的定性对比&#xff0c;对局部放大以观察细节效果。如下 对单张渲染后的图像&#xff0c;选择指定区域并进行放大操作&#xff0c;然后将原始图像、处理后的两个区域以及标记连线的新图像&#xff0c;如下图 代码 from PIL import Image, ImageDraw# 读…