文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

系统设计基础之长轮询、WebSocket、服务器发送事件(SSEs)协议

2024-12-03 13:09

关注

本文转载自微信公众号「Java大厂面试官 」,作者laker 。转载本文请联系Java大厂面试官 公众号。   

生活只有两种选择:重新出发,做自己生命的主角;抑或停留在原地,做别人的配角。

长轮询、WebSocket和服务器发送事件有什么区别

长轮询,WebSocket和服务器发送事件是客户端和服务器(如Web浏览器和Web服务器)之间流行的通信协议。首先,让我们了解标准HTTP Web请求。以下是常规HTTP请求的一系列事件:

  1. 客户端打开连接并从服务器请求数据。
  2. 服务器计算响应。
  3. 服务器根据打开的请求将响应发送回客户端。

Ajax轮询协议

轮询是绝大多数AJAX应用程序使用的一种标准技术。基本思想是客户端反复轮询(或请求)服务器以获取数据。客户端发出请求,并等待服务器响应数据。如果没有可用数据,则返回空响应。

  1. 客户端使用常规HTTP打开连接并从服务器请求数据。
  2. 所请求的网页以固定间隔将请求发送到服务器(例如0.5秒)。
  3. 服务器计算响应并将其发送回,就像常规HTTP流量一样。
  4. 客户端定期重复上述三个步骤,以从服务器获取更新。

轮询的问题在于客户端必须不断向服务器询问任何新数据。会照成许多空响应,从而造成HTTP开销。

HTTP长轮询协议

这是传统轮询技术的一种变体,该技术允许服务器在数据可用时将信息推送到客户端。使用Long-Polling,客户端可以像正常轮询一样从服务器请求信息,但是服务器可能不会立即响应。这就是为什么这种技术有时被称为“挂起请求”的原因。

使用HTTP Long-Polling的应用程序的基本生命周期如下:

WebSockets协议

WebSocket提供全双工单个TCP连接上的通信通道。它提供了客户端和服务器之间的持久连接,双方都可以使用该连接随时开始发送数据。客户端通过称为WebSocket握手的过程建立WebSocket连接。如果该过程成功,则服务器和客户端可以随时在两个方向上交换数据。WebSocket协议使客户端和服务器之间的通信具有较低的开销,从而促进了与服务器之间的实时数据传输。通过提供一种标准化的方法,使服务器无需客户端询问即可将内容发送到浏览器,并允许消息在保持连接打开的情况下来回传递。

服务器发送事件协议(SSEs)

在SSEs下,客户端与服务器建立持久的长期连接。服务器使用此连接将数据发送到客户端。如果客户端要向服务器发送数据,则需要使用另一种技术/协议。

  1. 客户端使用常规HTTP向服务器请求数据。
  2. 所请求的网页将打开与服务器的连接。
  3. 只要有新信息可用,服务器就会将数据发送到客户端。

当我们需要从服务器到客户端的实时流量,或者服务器正在循环生成数据并将向客户端发送多个事件时,SSEs最好。

总结

常见的前后端消息通信协议如下:

SSEs协议剖析

其中除了SSEs协议,其他方法大家都很熟悉了,再来看看SSEs到底是个啥?

SSE,即 Server-Sent Events,又叫 EventSource,是一种已被写入 HTML 5 标准的服务端事件推送技术,它允许客户端和服务端之间建立一个单向通道,以让服务端向客户端单方向持续推送事件消息,SSE 适用于不需要从客户端发送数据,但要通过某些服务器操作进行更新的场景,例如股票行情、共享设施更新、好友状态更新等。

上面已经简介过其大致流程了,简单说,所谓SSE,就是浏览器向服务器发送一个HTTP请求,然后服务器不断单向地向浏览器推送“信息”(message)。这种信息在格式上很简单,就是“信息”加上前缀“data: ”,然后以“\n\n”结尾。

SSE与WebSocket有相似功能,都是用来建立浏览器与服务器之间的通信渠道。

两者的对比如下:

SSE Websocket
http 协议,可以直接运行于现有的代理服务器和认证技术 独立的 websocket 协议,需要服务器端支持
SSE是单向通道,只能服务器向浏览器端发送。 全双工通道,可以双向通信,功能更强
轻量级,实现简单 实现相对复杂
默认支持断线重连 需要自己实现心跳断线重连
文本传输 二进制传输
支持自定义发送的消息类型

客户端DEMO

  1. "text/javascript"
  2.     if (!!window.EventSource) { 
  3.         var source = new EventSource('push'); 
  4.         //打开连接 
  5.         source.addEventListener('open'function (evt) { 
  6.             // console.info("连接已经打开了"); 
  7.         }, false); 
  8.         //接收消息 
  9.         source.addEventListener('message'function (evt) { 
  10.             console.info(evt.data); 
  11.         }); 
  12.         //错误消息,及关闭通知 
  13.         source.addEventListener('error'function (evt) { 
  14.             // console.info(evt); 
  15.         }, false); 
  16.     } else { 
  17.         alert("浏览器不支持  SSE"
  18.     } 
  19.  

 

服务端DEMO

首先向客户端声明接下来发送的是事件流text/event-stream类型的数据,然后就可以向客户端多次发送消息。事件流是一个简单的文本流,仅支持 UTF-8 格式的编码。每条消息以一个空行作为分隔符。

  1. @RestController 
  2. public class SSEsController { 
  3.      //向浏览器发送数据 
  4.     @RequestMapping(value = "/push", produces = "text/event-stream"
  5.     public String push() throws InterruptedException { 
  6.         String msg = ...; 
  7.         //固定格式 
  8.         return "data:" + msg + "\n\n"
  9.     } 

SpringBoot 利用 SseEmitter 来支持 sse,无需上面繁琐的代码,有兴趣的可以自行百度

本文大部分篇幅是翻译的国外文章:

 

 

来源: Java大厂面试官内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯