前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >你还在使用 WebSocket 实现实时消息推送吗?

你还在使用 WebSocket 实现实时消息推送吗?

作者头像
良月柒
发布于 2024-04-15 02:10:13
发布于 2024-04-15 02:10:13
28700
代码可运行
举报
运行总次数:0
代码可运行

服务端向客户端推送数据的实现方案有哪几种?

我们常规实现这些需求的方案有以下三种

  • 轮询
  • websocket
  • SSE

轮询简介

在很久很久以前,前端一般使用轮询来进行服务端向客户端进行消息的伪推送,为什么说轮询是伪推送?因为轮询本质上还是通过客户端向服务端发起一个单项传输的请求,服务端对这个请求做出响应而已。通过不断的请求来实现服务端向客户端推送数据的错觉。并不是服务端主动向客户端推送数据。

显然,轮询一定是上述三个方法里最下策的决定。

轮询的缺点:

  • 首先轮询需要不断的发起请求,每一个请求都需要经过http建立连接的流程(比如三次握手,四次挥手),是没有必要的消耗。
  • 客户端需要从页面被打开的那一刻开始就一直处理请求。虽然每次轮询的消耗不大,但是一直处理请求对于客户端来说一定是不友好的。
  • 浏览器请求并发是有限制的。比如Chrome 最大并发请求数目为 6,这个限制还有一个前提是针对同一域名的,超过这一限制的后续请求将会被阻塞。而轮询意味着会有一个请求长时间的占用并发名额。
  • 而如果轮询时间较长,可能又没有办法非常及时的获取数据

websocket简介

websocket是一个双向通讯的协议,他的优点是,可以同时支持客户端和服务端彼此相互进行通讯。功能上很强大。

缺点也很明显,websocket是一个新的协议,ws/wss。也就是说,支持http协议的浏览器不一定支持ws协议。

相较于SSE来说,websocket因为功能更强大。结构更复杂。所以相对比较重。

websocket对于各大浏览器的兼容性↓

SSE简介

sse是一个单向通讯的协议也是一个长链接,它只能支持服务端主动向客户端推送数据,但是无法让客户端向服务端推送消息。

长链接是一种HTTP/1.1的持久连接技术,它允许客户端和服务器在一次TCP连接上进行多个HTTP请求和响应,而不必为每个请求/响应建立和断开一个新的连接。长连接有助于减少服务器的负载和提高性能。

SSE的优点是,它是一个轻量级的协议,相对于websockte来说,他的复杂度就没有那么高,相对于客户端的消耗也比较少。而且SSE使用的是http协议(websocket使用的是ws协议),也就是现有的服务端都支持SSE,无需像websocket一样需要服务端提供额外的支持。

注意:IE大魔王不支持SSE

SSE对于各大浏览器的兼容性↓

注意哦,上图是SSE对于浏览器的兼容不是对于服务端的兼容。

websocket和SSE有什么区别?

轮询

对于当前计算机的发展来说,几乎很少出现同时不支持websocket和sse的情况,所以轮询是在极端情况下浏览器实在是不支持websocket和see的下策。

Websocket和SSE

我们一般的服务端和客户端的通讯基本上使用这两个方案。首先声明:这两个方案没有绝对的好坏,只有在不同的业务场景下更好的选择。

SSE的官方对于SSE和Websocket的评价是

  • WebSocket是全双工通道,可以双向通信,功能更强;SSE是单向通道,只能服务器向浏览器端发送。
  • WebSocket是一个新的协议,需要服务器端支持;SSE则是部署在HTTP协议之上的,现有的服务器软件都支持。
  • SSE是一个轻量级协议,相对简单;WebSocket是一种较重的协议,相对复杂。
  • SSE默认支持断线重连,WebSocket则需要额外部署。
  • SSE支持自定义发送的数据类型。

Websocket和SSE分别适用于什么业务场景?

对于SSE来说,它的优点就是轻,而且对于服务端的支持度要更好。换言之,可以使用SSE完成的功能需求,没有必要使用更重更复杂的websocket。

比如:数据大屏的实时数据,消息中心的消息推送等一系列只需要服务端单方面推送而不需要客户端同时进行反馈的需求,SSE就是不二之选。

对于Websocket来说,他的优点就是可以同时支持客户端和服务端的双向通讯。所适用的业务场景:最典型的就是聊天功能。这种服务端需要主动向客户端推送信息,并且客户端也有向服务端推送消息的需求时,Websocket就是更好的选择。

SSE有哪些主要的API?

建立一个SSE链接 :var source = new EventSource(url);

SSE连接状态

source.readyState

  • 0,相当于常量EventSource.CONNECTING,表示连接还未建立,或者连接断线。
  • 1,相当于常量EventSource.OPEN,表示连接已经建立,可以接受数据。
  • 2,相当于常量EventSource.CLOSED,表示连接已断,且不会重连。

SSE相关事件

  • open事件(连接一旦建立,就会触发open事件,可以定义相应的回调函数)
  • message事件(收到数据就会触发message事件)
  • error事件(如果发生通信错误(比如连接中断),就会触发error事件)

数据格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Content-Type: text/event-stream //文本返回格式
Cache-Control: no-cache  //不要缓存
Connection: keep-alive //长链接标识

SSE相关文档:

https://www.w3cschool.cn/nwfchn/wpi3cozt.html

显然,如果直接看api介绍不论是看这里还是看官网,大部分同学都是比较懵圈的状态,那么我们写个demo来看一下?

我更建议您先把Demo跑起来,然后在看看上面这个w3cschool的SSE文档。两个配合一起看,会更方便理解些。

如何实操一个SSE链接?Demo↓

这里Demo前端使用的就是最基本的html静态页面连接,没有使用任何框架。

后端选用语言是node,框架是Express。

理论上,把这两段端代码复制过去跑起来就直接可以用了。

  • 第一步,建立一个index.html文件,然后复制前端代码Demo到index.html文件中,打开文件
  • 第二步,进入一个新的文件夹,建立一个index.js文件,然后将后端Demo代码复制进去,然后在该文件夹下执行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm init          //初始化npm       
npm i express     //下载node express框架
node index        //启动服务

在这一层文件夹下执行命令。

完成以上操作就可以把项目跑起来了

前端代码Demo

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!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>
    <ul id="ul">
        
    </ul>
</body>
<script>

//生成li元素
function createLi(data){
    let li = document.createElement("li");
    li.innerHTML = String(data.message);
    return li;
}
    
//判断当前浏览器是否支持SSE
  let source = ''
 if (!!window.EventSource) {
    source = new EventSource('http://localhost:8088/sse/');
 }else{
    throw new Error("当前浏览器不支持SSE")
 }

 //对于建立链接的监听
 source.onopen = function(event) {
   console.log(source.readyState);
   console.log("长连接打开");
 };

 //对服务端消息的监听
 source.onmessage = function(event) {
   console.log(JSON.parse(event.data));
   console.log("收到长连接信息");
   let li = createLi(JSON.parse(event.data));
   document.getElementById("ul").appendChild(li)
 };

 //对断开链接的监听
 source.onerror = function(event) {
   console.log(source.readyState);
   console.log("长连接中断");
 };

</script>
</html>

后端代码Demo(node的express)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const express = require('express'); //引用框架
const app = express(); //创建服务
const port = 8088; //项目启动端口

//设置跨域访问
app.all("*", function(req, res, next) {
 //设置允许跨域的域名,*代表允许任意域名跨域
 res.header("Access-Control-Allow-Origin", '*');
 //允许的header类型
 res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
 //跨域允许的请求方式 
 res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
 // 可以带cookies
 res.header("Access-Control-Allow-Credentials", true);
 if (req.method == 'OPTIONS') {
  res.sendStatus(200);
 } else {
  next();
 }
})

app.get("/sse",(req,res) => {
    res.set({
        'Content-Type': 'text/event-stream', //设定数据类型
        'Cache-Control': 'no-cache',// 长链接拒绝缓存
        'Connection': 'keep-alive' //设置长链接
      });

      console.log("进入到长连接了")
      //持续返回数据
      setInterval(() => {
        console.log("正在持续返回数据中ing")
        const data = {
          message: `Current time is ${new Date().toLocaleTimeString()}`
        };
        res.write(`data: ${JSON.stringify(data)}\n\n`);
      }, 1000);  
})

//创建项目
app.listen(port, () => {
 console.log(`项目启动成功-http://localhost:${port}`)
})

总结

  • SSE比websocket更轻
  • SSE是基于http/https协议的
  • websocket是一个新的协议,ws/wss协议
  • 如果只需要服务端向客户端推送消息,推荐使用SSE
  • 如果需要服务端和客户端双向推送,请选择websocket
  • 不论是SSE还是websocket,对于浏览器的兼容性都不错
  • 轮询是下策,很占用客户端资源,不建议使用。(不过偷懒的时候他确实方便)
  • IE不支持SSE
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的成长之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
消息推送技术,除了websocket还知道那些?
WebSocket是一种网络通信协议,它提供了在单个TCP连接上进行全双工通信的能力。这意味着数据可以在客户端和服务器之间双向流动,而无需客户端通过轮询或重复请求来获取更新。
老K博客
2024/06/01
7740
消息推送技术,除了websocket还知道那些?
我有 7种 实现web实时消息推送的方案,7种!
做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能。
程序员小富
2022/07/19
11.2K0
我有 7种 实现web实时消息推送的方案,7种!
SSE技术详解:使用 HTTP 做服务端数据推送应用的技术
 SSE ( Server-sent Events )是 WebSocket 的一种轻量代替方案,使用 HTTP 协议。
用户7353950
2022/05/10
9.8K0
SSE技术详解:使用 HTTP 做服务端数据推送应用的技术
springBoot集成websocket实时消息推送
知识浅谈
2023/11/17
2.3K0
传统轮询、长轮询、服务器发送事件与WebSocket
构建网络应用的过程中,我们经常需要与服务器进行持续的通讯以保持双方信息的同步。通常这种持久通讯在不刷新页面的情况下进行,消耗一定的内存资源常驻后台,并且对于用户不可见。本文将简要介绍Web通信中常用的四种方式。
kirin
2021/05/08
3.1K0
websocket消息推送设计
公司内目前有几个项目都有消息推送的功能,例如:某个业务操作之后需要推送消息给前端页面,让用户实时感知。
lyb-geek
2022/11/18
4.7K0
websocket消息推送设计
带你揭开WebSocket的神秘面纱!
在揭开webSocket的神秘面纱之前,有言在先,我在写文章之前对webSocket一无所知,由于公司业务用到,故此研究记录一下,班门弄斧之处,请大佬批评指正!
用户7413032
2020/06/11
1.1K0
带你揭开WebSocket的神秘面纱!
重学Springboot系列之服务器推送技术
若干年前,所有的请求都是由浏览器端发起,浏览器本身并没有接受请求的能力。所以一些特殊需求都是用ajax轮询的方式来实现的。比如:
大忽悠爱学习
2021/12/07
2.3K0
重学Springboot系列之服务器推送技术
「首席看应用架构」轮询,SSE 和WebSocket,如何选择合适的?
构建实时Web应用程序有点挑战,我们需要考虑如何将数据从服务器发送到客户端。能够“主动”实现这一功能的技术已经存在了很长时间,并且仅限于两种通用方法:客户端请求或服务器请求。
架构师研究会
2019/09/26
4.2K0
「首席看应用架构」轮询,SSE 和WebSocket,如何选择合适的?
Comet,SSE,WebSocket前后端的实现
Comet(服务器推送)的两种方式 短轮询 页面定时向服务器发送请求, 步骤为:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接 //前端js var xhr = new XMLHttpRequest(); setInterval(()=>{ xhr.onreadystatechange = function () { if (xhr.readyState == 4) { let result = xhr.responseText
chuchur
2022/10/25
8520
AI大模型文本流如何持续吐到前端,服务端实时通信技术 SSE(Server-Sent Events) 认知
99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式
山河已无恙
2025/02/25
2750
AI大模型文本流如何持续吐到前端,服务端实时通信技术 SSE(Server-Sent Events) 认知
PHP结合JavaScript SSE(流式显示)实现服务器实时推送功能
SSE 的全称是 Server Sent Events,即服务器推送事件。它是一种基于 HTTP 的服务器到客户端的单向(半双工)通信机制,使服务器能够主动将实时数据推送给客户端,而不需要客户端多次发起请求。 官方文档:https://developer.mozilla.org/en-US/docs/Web/API/EventSource
超级小可爱
2024/03/26
8740
服务器端实时推送技术之SSE
在讲Server-Sent Events (SSE) 之前,我们先来看看 HTTP 请求- 响应。一个标准的 HTTP 请求- 响应,需要客户端打开一个连接,将一个 HTTP 请求(如 HTTP GET 请求)发送到服务端,然后接收到 HTTP 回来的响应,如果该响应被完全发送或者接收,服务端就会把连接关闭。通常是由某个客户发起,客户端才会需要请求所有数据。
kinbug [进阶者]
2020/06/27
3.7K0
服务器端实时推送技术之SSE
ChatGPT对话为什么不用WebSocket而使用EventSource?
在构建基于浏览器的实时对话系统时,开发者通常会选择使用WebSocket作为实现实时通信的协议。然而,有些场景下,使用EventSource作为替代方案也是一个值得考虑的选择。本文将深入探讨为什么ChatGPT对话系统选择使用EventSource而非WebSocket,并通过代码示例和详细解释,帮助读者理解这一决策的原因。
IT_陈寒
2023/12/18
5800
ChatGPT对话为什么不用WebSocket而使用EventSource?
每日一博 - Server-Sent Events推送技术
SSE(Server-Sent Events)是一种基于HTTP的服务器推送技术,它允许服务器实时地向客户端推送数据。相比于传统的轮询或长轮询技术,SSE具有更低的延迟、更高的效率和更低的资源消耗。
小小工匠
2023/07/11
1.1K0
每日一博 - Server-Sent Events推送技术
SSE 服务端消息推送
SSE 它是基于 HTTP 协议的,一般意义上的 HTTP 协议是无法做到服务端主动向客户端推送消息的。有一种变通方法,就是服务器向客户端声明,发送的是流信息,本质上,这种通信就是以流信息的方式。
默存
2022/12/03
2.2K0
网页端IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket
对Web端即时通讯技术熟悉的开发者来说,我们回顾网页端IM的底层通信技术,从短轮询、长轮询,到后来的SSE以及WebSocket,使用门槛越来越低(早期的长轮询Comet这类技术实际属于hack手段,使用门槛并不低),技术手段越来越先进,网页端即时通讯技术的体验也因此越来越好。
JackJiang
2021/05/25
1.7K0
聊聊四种实时通信技术:长轮询、短轮询、WebSocket 和 SSE
这篇文章,我们聊聊 四种实时通信技术:短轮询、长轮询、WebSocket 和 SSE 。
勇哥java实战
2025/04/23
2740
javaweb实现即时消息推送功能
在浏览某些网页的时候,例如 WebQQ、京东在线客服服务、CSDN私信消息等类似的情况下,我们可以在网页上进行在线聊天,或者即时消息的收取与回复,可见,这种功能的需求由来已久,并且应用广泛。
全栈程序员站长
2022/08/23
2.1K0
javaweb实现即时消息推送功能
PHP 与 JavaScript SSE:实现服务器实时推送功能的绝佳组合
SSE 的全称是 Server Sent Events,即服务器推送事件。它是一种基于 HTTP 的服务器到客户端的单向(半双工)通信机制,使服务器能够主动将实时数据推送给客户端,而不需要客户端多次发起请求。 官方文档:https://developer.mozilla.org/en-US/docs/Web/API/EventSource
Tinywan
2023/10/22
1.6K0
PHP 与 JavaScript SSE:实现服务器实时推送功能的绝佳组合
推荐阅读
相关推荐
消息推送技术,除了websocket还知道那些?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验