0


实时通信的服务器推送机制 EventSource(SSE) 简介,附 go 实现示例

简介

不知道大家有没有见过

Content-Type:text/event-stream

的请求头,这是

HTML5

中的

EventSource

是一项强大的

API

,通过服务器推送实现实时通信。

WebSocket

相比,

EventSource

提供了一种简单而可靠的单向通信机制(服务器->客户端),实现简单,适用于许多实时应用场景。

本文将介绍

EventSource

的简单使用、与

WebSocket

的对比以及其优缺点,最后对其进行总结。

EventSource

客户端从服务端订阅一条“流”,之后服务端可以发送消息给客户端直到服务端或者客户端关闭该“流”,所以

EventSource

也叫作

SSE(server-sent-event)

  • EventSourceHTML5 中的一项 API,用于在客户端和服务器之间建立持久的、单向的通信连接。
  • 它基于 HTTP 协议,通过服务器推送的方式向客户端发送实时事件通知。
  • 客户端通过添加事件侦听器来捕获事件并执行相应的操作。

简单使用

示例:
服务器端使用

Go

创建了一个路由

/events

,当客户端通过

EventSource

对象连接到该路由时,服务器会不断地发送事件流(每隔2秒发送一个事件)。客户端的

HTML

页面中使用

JavaScript

创建了一个

EventSource

对象,通过

onmessage

事件,将接收到的事件数据添加到页面中。如果发生错误,客户端会关闭

EventSource

连接。

文件结构如下

程序目录
    - main.go
    - c1.html

go 服务

package main

import("fmt""gopkg.in/antage/eventsource.v1""log""net/http""time")funcmain(){
    es := eventsource.New(nil,nil)defer es.Close()

    http.Handle("/", http.FileServer(http.Dir("./")))
    http.Handle("/events", es)gofunc(){for{// 每2秒发送一条当前时间消息,并打印对应客户端数量
            es.SendEventMessage(fmt.Sprintf("hello, now is: %s", time.Now()),"","")
            log.Printf("Hello has been sent (consumers: %d)", es.ConsumersCount())
            time.Sleep(2* time.Second)}}()

    log.Println("Open URL http://localhost:8080/ in your browser.")
    err := http.ListenAndServe(":8080",nil)if err !=nil{
        log.Fatal(err)}}

前端 HTML

<!DOCTYPEhtml><html><head><title>SSE test</title><scripttype="text/javascript">
        window.addEventListener("DOMContentLoaded",function(){var evsrc =newEventSource("http://localhost:8080/events");varmsgEvent=function(ev){
                document.getElementById("log").insertAdjacentHTML("beforeend","<li>"+ ev.data +"</li>");}
            evsrc.onmessage = msgEvent;//evsrc.addEventListener("message", msgEvent)
            evsrc.onerror=function(ev){
                console.log("readyState = "+ ev.currentTarget.readyState);}})</script></head><body><h1>SSE test</h1><div><ulid="log"></ul></div></body></html>

服务启动后访问 http://localhost:8080/c1.html 可见如下页面
在这里插入图片描述

和 websocket 的对比

EventSource 的优点

  • 简单易用:EventSource 使用简单,基于标准的 HTTP 协议,无需复杂的握手过程。
  • 自动重连:EventSource 具有内置的重连机制,确保连接中断后自动重新连接。
  • 轻量级:EventSource 使用长轮询机制,消耗的资源相对较少,适合低带宽环境。
  • 跨域支持:EventSource 允许在跨域环境下进行通信,通过适当的响应头授权来自不同域的客户端连接。

EventSource 的缺点

  • 单向通信:EventSource 只支持服务器向客户端的单向通信,无法实现客户端向服务器的实时交互。
  • 较低的浏览器支持:尽管现代浏览器广泛支持 EventSource,但在一些较旧的浏览器中可能不完全支持。

WebSocket 的优点

  • 双向通信:WebSocket 支持全双工通信,客户端和服务器可以在同一连接上进行双向数据交换。
  • 实时性和效率:WebSocket 具有低延迟和高效性能,适用于需要快速、实时响应的应用。
  • 大规模应用:WebSocket适用于复杂的、大规模的实时应用,如在线游戏、协同编辑等。

WebSocket 的缺点

  • 复杂性:WebSocket协议的握手过程相对复杂,需要服务器和客户端实现特定的协议逻辑。
  • 难以穿越防火墙和代理服务器:WebSocket的特殊协议可能会受到防火墙和代理服务器的限制。

总结

EventSource

HTML5

中一个强大的

API

,提供了简单可靠的服务器推送机制,用于实现实时通信。

WebSocket

相比,

EventSource

的优势在于其简单易用、自动重连、轻量级和跨域支持。然而,它也有一些限制,如单向通信和较低的浏览器支持。相比之下,

WebSocket

适用于双向通信、大规模应用和实时性要求较高的场景,但其复杂性和穿越防火墙的挑战也需要考虑。

总的来说,

EventSource

是一种非常有用的

API

,适用于许多实时应用场景,如实时股票报价、即时聊天、实时通知等。它提供了一种简单而可靠的方式来建立服务器推送连接,并实现实时更新和通知。如果应用程序只需要服务器向客户端单向推送数据,

EventSource

是一个不错的选择。然而,如果需要双向通信或更高级的实时功能,

WebSocket

可能更适合。

参考

  • Mozilla Developer Network (MDN) - EventSource
  • Stream Updates with Server-Sent Events

本文转载自: https://blog.csdn.net/DisMisPres/article/details/130539861
版权归原作者 Grassto 所有, 如有侵权,请联系我们删除。

“实时通信的服务器推送机制 EventSource(SSE) 简介,附 go 实现示例”的评论:

还没有评论