Eventsource

eventsource · 浏览次数 : 36

小编点评

**背景** 当您使用 chatGPT 时,服务端可以实时向您推送答案。然而,在早期版本中,它们使用的是 WebSocket 技术。随着 WebSocket 的普及,服务端已放弃了使用 WebSocket 的机制。 **EventSource** EventSource 是 HTML5 中的一种强大的 API,它提供了一种简单可靠的服务器推送机制,用于实现实时通信。与 WebSocket 相比,EventSource 的优势在于其简单易用、自动重连和跨域支持。 **WebSocket** WebSocket 是一个双向通信技术,允许客户端和服务器在同一连接上进行双向数据交换。它具有低延迟和高效性能,适用于需要快速、实时响应的应用。 **Demo** **4.1 后端** ```go package main import ( "fmt" "log" "net/http" "time" "gopkg.in/antage/eventsource.v1" ) func main() { es := eventsource.New(nil, nil) defer es.Close() http.Handle("/", http.FileServer(http.Dir("/"))) http.Handle("/events", es) go func() { for { // 每 2 秒发送一条当前时间消息 fmt.Printf("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.") } ``` **4.2 前端** ```html SSE test

SSE test

    ``` **4.3 效果图** 这是一个实时显示事件源消息的图像: ``` hello, now is: 2023-04-05 14:15:00 hello, now is: 2023-04-05 14:15:10 ... ```

    正文

    1、背景

    当我使用chatGpt时,服务端可以实时像我推送答案。起初以为是用了websocket技术,但是后来发现是用了Eventsource

    2、什么是Eventsource

    不知道大家有没有见过 Content-Type:text/event-stream 的请求头,这是 HTML5 中的 EventSource 是一项强大的 API,通过服务器推送实现实时通信。

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

    3、与ws的对比

    3.1、EventSource 的优点

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

    3.2、EventSource 的缺点

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

    3.3、WebSocket 的优点

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

    3.4、WebSocket 的缺点

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

    总结

    EventSource 是 HTML5 中一个强大的 API,提供了简单可靠的服务器推送机制,用于实现实时通信。
    与 WebSocket 相比,EventSource 的优势在于其简单易用、自动重连、轻量级和跨域支持。然而,它也有一些限制,如单向通信和较低的浏览器支持。相比之下,WebSocket 适用于双向通信、大规模应用和实时性要求较高的场景,但其复杂性和穿越防火墙的挑战也需要考虑。
    总的来说,EventSource 是一种非常有用的 API,适用于许多实时应用场景,如实时股票报价、即时聊天、实时通知等。它提供了一种简单而可靠的方式来建立服务器推送连接,并实现实时更新和通知。如果应用程序只需要服务器向客户端单向推送数据,EventSource 是一个不错的选择。然而,如果需要双向通信或更高级的实时功能,WebSocket 可能更适合。

    4、实现一个demo

    4.1、后端:

    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    	"time"
    
    	"gopkg.in/antage/eventsource.v1"
    )
    
    func main() {
    	es := eventsource.New(nil, nil)
    	defer es.Close()
    
    	http.Handle("/", http.FileServer(http.Dir("./")))
    	http.Handle("/events", es)
    	go func() {
    		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)
    	}
    }
    

    4.2、前端:

    <!DOCTYPE html>
    <html>
    <head>
        <title>SSE test</title>
        <script type="text/javascript">
            window.addEventListener("DOMContentLoaded", function () {
                var evsrc = new EventSource("http://localhost:8080/events");
                var msgEvent = 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>
        <ul id="log">
        </ul>
    </div>
    </body>
    </html>
    

    4.3 效果图:

    与Eventsource相似的内容: