Posted in

如何在 Go 中实现服务器推送事件_AI阅读总结 — 包阅AI

包阅导读总结

1. 关键词:

Server-Sent Events、Go、实时通信、实现、应用场景

2. 总结:

本文介绍了在 Go 中实现 Server-Sent Events(SSE)的方法,包括其优势、应用场景、实现代码示例,还提到了客户端接收事件的方式、SSE 实现的关键组件、最佳实践等,指出 SSE 为 Go 应用提供了高效的实时通信方式。

3. 主要内容:

– 什么是 Server-Sent Events

– 是一种服务器向客户端推送数据的网络技术

– 单向通信,比 WebSockets 简单,有浏览器原生支持、自动重连等优点

– 如何在 Go 中实现 SSE

– 示例代码:创建简单的 SSE 服务器,每秒发送带当前时间戳的数据

– 关键组件:包括消息编码、响应头设置、检测断开等

– 如何在客户端接收事件

– 使用浏览器的 EventSource 接口

– SSE 在 Go 中的最佳实践

– 事件格式化:可使用 JSON 等结构化格式

– 重连策略和错误处理

– 负载均衡

– SSE 的应用场景

– 实时仪表盘、体育比分、社交媒体动态等

– 结论:SSE 为 Go 应用提供高效实时通信,开发时要考虑多方面因素

思维导图:

文章地址:https://www.freecodecamp.org/news/how-to-implement-server-sent-events-in-go/

文章来源:freecodecamp.org

作者:Alex Pliutau

发布时间:2024/8/28 14:07

语言:英文

总字数:985字

预计阅读时间:4分钟

评分:85分

标签:服务器推送事件,Go 编程,实时通信,Web 开发,HTTP 流


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

Server-Sent Events (SSE) is a powerful technology that enables real-time, unidirectional communication from servers to clients.

In this article, we’ll explore how to implement SSE in Go, discussing its benefits, use cases, and providing practical examples. By the end, you should know the basics of building real-time applications with efficient, unidirectional communication.

What are Server-Sent Events?

SSE is a web technology that allows servers to push data to clients over a single HTTP connection.

Unlike WebSockets, SSE is unidirectional, making it simpler to implement and ideal for scenarios where real-time updates from the server are required, but client-to-server communication is not necessary.

Developing a web application that uses SSE is straightforward. You’ll need a bit of code on the server to stream events to the front-end, but the client side code works almost identically to websockets when it comes to handling incoming events. This is a one-way connection, so you can’t send events from a client to a server.

Benefits of SSE

  1. Simplicity: SSE is easier to implement compared to WebSockets.

  2. Native browser support: Most modern browsers support SSE out of the box.

  3. Automatic reconnection: Clients automatically attempt to reconnect if the connection is lost.

  4. Efficient: Uses a single HTTP connection, reducing overhead.

How to Implement SSE in Go

For our example here, we’ll create a simple SSE server in Go which just sends the data to the client every second with a current timestamp. The client can then connect to our server on port 8080 and receive these messages.

A real example could be something more sophisticated like sending notifications, displaying progress bar updates, and so on.

package mainimport (    "fmt"    "net/http"    "time")func sseHandler(w http.ResponseWriter, r *http.Request) {        w.Header().Set("Content-Type", "text/event-stream")    w.Header().Set("Cache-Control", "no-cache")    w.Header().Set("Connection", "keep-alive")        w.Header().Set("Access-Control-Allow-Origin", "*")        clientGone := r.Context().Done()    rc := http.NewResponseController(w)    t := time.NewTicker(time.Second)    defer t.Stop()    for {        select {        case <-clientGone:            fmt.Println("Client disconnected")            return        case <-t.C:                                    _, err := fmt.Fprintf(w, "data: The time is %s\n\n", time.Now().Format(time.UnixDate))            if err != nil {                return            }            err = rc.Flush()            if err != nil {                return            }        }    }}func main() {    http.HandleFunc("/events", sseHandler)    fmt.Println("server is running on :8080")    if err := http.ListenAndServe(":8080", nil); err != nil {        fmt.Println(err.Error())    }}

Key Components of the SSE Implementation

The event stream is a simple stream of text data which must be encoded using UTF-8. Messages in the event stream are separated by a pair of newline characters – \n\n. A colon as the first character of a line is in essence a comment, and is ignored.

In our server it is done here:

rc := http.NewResponseController(w)fmt.Fprintf(w, "data: The time is %s\n\n", time.Now().Format(time.UnixDate))rc.Flush()

The server that sends events needs to respond using the MIME type text/event-stream. We do it by setting the response header here:

w.Header().Set("Content-Type", "text/event-stream")

You may have noticed that we set few other headers as well. One is to keep the HTTP connection open, and another to bypass CORS:

w.Header().Set("Cache-Control", "no-cache")w.Header().Set("Connection", "keep-alive")w.Header().Set("Access-Control-Allow-Origin", "*")

And the last important piece is to detect the disconnect. In Go, we’ll receive it as a message in a specified channel:

clientGone := r.Context().Done()for {    select {    case <-clientGone:        fmt.Println("Client disconnected")        return    }}

Each message received has some combination of the following fields, one per line. In our server we send only the data field which is enough, as other fields are optional. More details here.

  • event – a string identifying the type of event described.

  • data – the data field for the message.

  • id – the event ID to set the EventSource object’s last event ID value.

  • retry – the reconnection time.

How to Receive the Events on the Client Side

On the front end or client side, you will have to use the EventSource interface. It’s a browser API encapsulating Server-Sent Events. In the following example, our browser application receives the events from the server and prints them in a list.

<!doctype html><html>    <body>        <ul id="list"></ul>    </body>    <script type="text/javascript">        const eventSrc = new EventSource("http://127.0.0.1:8080/events");        const list = document.getElementById("list");        eventSrc.onmessage = (event) => {            const li = document.createElement("li");            li.textContent = `message: ${event.data}`;            list.appendChild(li);        };    </script></html>

Here is how it may look in your browser:

logs

Best Practices for SSE in Golang

Event Formatting

In a real world project, a simple string of data may not be enough. In these cases, using a structured format like JSON can be a good option to send multiple data fields once. Here’s an example:

{  "status": "in_progress",  "completion": 51.22}

Reconnection Strategy and Error Handling

Something could always go wrong on both sides: the server might reject the connection for some reason or a client might abruptly disconnect.

In each case, you’ll need to implement a backoff strategy for graceful reconnections. It’s better to miss one message than completely break the event loop.

In JavaScript, you can check for errors in EventSource and then act accordingly:

eventSrc.onerror = (err) => {  console.error("EventSource failed:", err);};

Load Balancing

For high-traffic applications, you may consider using a Load Balancer, for example NGINX. If you plan to have many clients connecting to your server, it’s good to test it beforehand by simulating the load from the clients.

Use Cases for SSE

  1. Real-time dashboards

  2. Live sports scores

  3. Social media feeds

  4. Stock market tickers

  5. Progress indicators for long-running tasks

Conclusion

Server-Sent Events provide an efficient and straightforward way to implement real-time, server-to-client communication in Golang applications. By leveraging SSE, developers can create responsive and dynamic web applications with minimal overhead and complexity.

As you build your SSE-powered applications, remember to consider scalability, error handling, and client-side implementation to ensure a robust and efficient real-time communication system.

Explore more articles from packagemain.tech