从长轮询到 Server-Sent Events,服务端实时推送


前端开发中,我们经常需要向后端请求数据,并更新页面展示。从最早的轮询到现在的长轮询和 Server-Sent
Events,我们的技术手段也在不断地更新和升级。在本文中,我们将详细介绍长轮询和 Server-Sent Events
技术的原理和使用方法,并给出相应的示例代码,希望可以对前端开发同学有所指导和帮助。

长轮询技术

长轮询技术(long polling),也叫做 Comet
技术,是一种在客户端和服务器之间实现实时双向数据交互的技术。长轮询的原理是客户端发起请求后,服务器并没有立即返回数据,而是一直保持这个连接处于“等待”的状态。当服务器有数据可返回时,才会将数据返回给客户端,并断开连接。客户端接收到数据后会再次向服务器发起请求,重复上述过程。

长轮询的优点是真正实现实时数据交互,不需要定时的轮询,避免了不必要的请求,减少了数据传输的开销,同时还能保持连接的长期有效。它适用于对实时数据变化有较高需求的应用中,如在线聊天、实时通知等。

长轮询的缺点是需要持久化连接,占用服务器资源,容易导致服务器负载过高。同时,如果服务器在返回数据前发生异常或者网络故障等问题,会导致连接一直处于“等待”状态,形成“长尾”并且一直占用资源。

下面是一个长轮询的示例代码:

function longPolling() {  
    // 发起请求  
  fetch('/api/data')  
    .then(function(response) {  
        // 处理数据  
      console.log(response.data);  
      // 再次发起请求  
      longPolling();  
    })  
    .catch(function(error) {  
        // 处理错误  
      console.log(error);  
      // 延迟一段时间再次发起请求  
      setTimeout(longPolling, 5000);  
    });  
}  
longPolling();  

上述代码中,发起请求后如果服务器有数据可返回,就会调用 then 方法,处理数据并再次发起请求。如果请求发生错误,则调用 catch
方法,处理错误并延迟一段时间再次发起请求。

Server-Sent Events 技术

与长轮询相比,Server-Sent Events 技术(SSE)更为高效,是一种轻量级的实时数据推送技术。SSE
的原理是在客户端与服务器之间建立一个单向连接,服务器可以主动向客户端发送数据,而客户端仅需等待服务器推送的数据。

SSE
的优点是不需要像长轮询那样持久化连接,不会占用大量的服务器资源。同时,它还支持事件类型、重连机制、自定义消息数据等高级特性,拓展了开发者对实时应用场景的应用场景。

SSE 的缺点是他依赖浏览器的 EventSource 接口,目前对于老版本的浏览器需增加额外的兼容代码。

下面是一个 SSE 的示例代码:

var source = new EventSource('/api/data');  
source.addEventListener('message', function(event) {  
    // 处理数据  
  console.log(event.data);  
});  
source.addEventListener('error', function(event) {  
    // 处理错误  
  console.log(event.target.readyState);  
});  

上述代码中,我们创建了一个 EventSource 对象,并监听了 messageerror
两个事件。当服务器推送数据时,会触发 message 事件并传递数据到回调函数中进行处理。如果连接错误或关闭,就会触发 error
事件,我们可以在这个事件回调函数中处理相应的错误信息。

总结

长轮询和 Server-Sent Events
技术都能够实现实时数据交互,具有各自的优点和缺点,开发者应该根据自身的应用场景和需求选择合适的技术手段。同时,我们也需要结合自身的业务场景,考虑如何优化连接和数据传输,减少不必要的资源占用和性能损失。希望这篇文章能为大家在前端实时交互方面提供参考和帮助。