当前位置: 首页 > 科技观察

系统设计基础:长轮询、WebSocket、ServerSentEvents(SSEs)Protocol

时间:2023-03-17 22:50:24 科技观察

转载本文请联系Java大厂面试官公众号。人生只有两种选择:重新开始,做自己人生的主角;或者留在原地,做别人的配角。长轮询、WebSocket和服务器发送事件之间有什么区别?AjaxPollingProtocolHTTPLongPollingProtocolWebSocketsProtocolServer-SentEventsProtocol(SSEs)SummarySSEsProtocol剖析ClientDEMOServerDEMOLongPolling,WebSocketandServerSentEvents有什么区别Longpolling,WebSocket,andServerSentEvents是流行的通信方式客户端和服务器(例如Web浏览器和Web服务器)之间的协议。首先,让我们了解一个标准的HTTPWeb请求。以下是常规HTTP请求的事件序列:客户端打开连接并从服务器请求数据。服务器评估响应。服务器根据打开的请求将响应发送回客户端。Ajax轮询协议轮询是大多数AJAX应用程序使用的标准技术。基本思想是客户端反复轮询(或请求)服务器以获取数据。客户端发出请求并等待服务器响应数据。如果没有可用数据,则返回空响应。客户端打开连接并使用常规HTTP从服务器请求数据。被请求的网页每隔一定时间(如0.5秒)向服务器发送请求。服务器计算响应并将其发回,就像常规HTTP流量一样。客户端周期性地重复上述三个步骤,从服务器获取更新。轮询的问题是客户端必须不断向服务器询问任何新数据。会导致很多空响应,造成HTTP开销。HTTP长轮询协议这是传统轮询技术的一种变体,它允许服务器在数据可用时将信息推送到客户端。使用长轮询,客户端可以像普通轮询一样向服务器请求信息,但服务器可能不会立即响应。这就是为什么这种技术有时被称为“挂起的请求”。如果服务器没有任何数据可供客户端使用,服务器将保留请求并等待直到有一些数据可用,而不是发送空响应。一旦数据可用,完整的响应将发送给客户端。然后客户端立即重新请求来自服务器的信息,这样服务器几乎总是有一个可用的等待请求,服务器可以使用该请求来响应事件。使用HTTP长轮询的应用程序的基本生命周期如下:客户端使用常规HTTP发出初始请求,然后等待响应。服务器延迟其响应,直到更新可用或直到发生超时。当更新可用时,服务器向客户端发送完整的响应。客户端通常会在收到响应后或在允许的等待时间暂停后立即发送新的长轮询请求。每个长轮询请求都有超时。连接因超时而关闭后,客户端必须定期重新连接。WebSockets协议WebSocket通过单个TCP连接提供全双工通信通道。它在客户端和服务器之间提供了一个持久连接,双方都可以使用它来随时开始发送数据。客户端通过称为WebSocket握手的过程建立WebSocket连接。如果该过程成功,则服务器和客户端可以随时双向交换数据。WebSocket协议以低开销实现客户端和服务器之间的通信,促进与服务器之间的实时数据传输。通过为服务器提供一种无需客户端请求即可向浏览器发送内容的标准化方式,并允许消息在保持连接打开的情况下来回传递。服务器发送事件(SSE)在SSE下,客户端与服务器建立持久的长期连接。服务器使用此连接向客户端发送数据。如果客户端想要向服务器发送数据,则需要使用另一种技术/协议。客户端使用常规HTTP从服务器请求数据。请求的网页将打开到服务器的连接。只要有新信息可用,服务器就会向客户端发送数据。当我们需要从服务器到客户端的实时流量时,或者当服务器在循环中生成数据并将向客户端发送多个事件时,SSE是最好的。常见的前后端消息通信协议总结如下:传统轮询协议Http长轮询协议WebSockets协议SSEs协议SSEs协议解析其中,除了SSEs协议之外的其他方式大家都比较熟悉。我们来看看SSE到底是什么?SSE,即Server-SentEvents,又称EventSource,是一种服务端事件推送技术,已经写入HTML5标准。它允许在客户端和服务端之间建立一个单向通道,使得服务端可以发送一个单一的方向持续推送事件消息,SSE适用于不需要客户端发送数据的场景,但是需要通过一定的服务器操作进行更新,比如股票行情、共享设施更新、好友状态更新等,大致流程上面已经介绍过了。简单的说,所谓SSE就是浏览器向服务器发送一个HTTP请求,然后服务器不断地向一个方向推送“消息”(message)给浏览器。这些信息的格式很简单,就是“信息”以“数据:”为前缀,然后以“\n\n”结尾。SSE和WebSocket功能相似,都是用来建立浏览器和服务器之间的通信通道。两者的对比如下:SSEWebsockethttp协议可以直接运行在现有的代理服务器和认证技术上。独立的websocket协议需要服务端的支持。SSE是一种单向通道,只能从服务器发送到浏览器。全双工通道,双向通信,功能更强大,轻量级,实现简单,实现相对复杂,默认支持断开重连,需要实现心跳,断开重连,文本传输,二进制传输,支持自定义消息types,clientlessDEMOserverDEMO首先发送客户端声明接下来发送的是事件流text/event-streamdata,然后可以多次向客户端发送消息。事件流是一个简单的文本流,只支持UTF-8编码。每条消息由一个空行分隔。@RestControllerpublicclassSSEsController{//向浏览器发送数据@RequestMapping(value="/push",produces="text/event-stream")publicStringpush()throwsInterruptedException{Stringmsg=...;//固定格式return"data:"+msg+"\n\n";}}SpringBoot使用SseEmitter来支持sse,不需要上面那些繁琐的代码。有兴趣的可以百度一下。本文大部分内容是翻译的国外文章:GrokkingtheSystemDesignInterviewbyDesignGurushttps://www.html5rocks.com/en/tutorials/eventsource/basics/https://blog.csdn.net/beng_shakalaka/article/详情/80792660