Golang SSE服务器推送

我正在尝试用Golang实现一个SSE(服务器推送事件)的服务端,但在实际使用中遇到了一些问题。客户端连接后,服务器只能推送一次消息,之后连接就断开了。我的代码大致是这样的:[贴出部分代码]。请问如何让服务器能够持续保持连接并多次推送消息?另外,当有大量客户端连接时,应该如何高效管理这些连接?有没有成熟的库或最佳实践可以推荐?

2 回复

使用Go实现SSE(Server-Sent Events)服务器推送,可通过net/http包实现。关键步骤:

  1. 设置响应头:Content-Type: text/event-streamCache-Control: no-cacheConnection: keep-alive
  2. 循环写入数据格式:data: {message}\n\n
  3. 使用http.Flusher强制刷新缓冲区

示例代码约20行,适合实时通知场景。

更多关于Golang SSE服务器推送的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,实现SSE(Server-Sent Events)服务器推送非常简单。SSE允许服务器通过HTTP连接向客户端推送实时数据,适用于实时通知、更新等场景。以下是一个完整的示例代码:

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"
)

func sseHandler(w http.ResponseWriter, r *http.Request) {
	// 设置SSE必需的响应头
	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", "*")

	// 创建通道用于发送消息
	messageChan := make(chan string)

	// 启动一个goroutine模拟数据生成
	go func() {
		for i := 1; i <= 10; i++ {
			message := fmt.Sprintf("消息 %d - 时间: %s", i, time.Now().Format("15:04:05"))
			messageChan <- message
			time.Sleep(2 * time.Second) // 每2秒发送一条消息
		}
		close(messageChan)
	}()

	// 监听客户端断开连接
	notify := w.(http.CloseNotifier).CloseNotify()
	
	for {
		select {
		case <-notify:
			log.Println("客户端断开连接")
			return
		case message, ok := <-messageChan:
			if !ok {
				return // 通道关闭,结束连接
			}
			// 按照SSE格式发送数据
			fmt.Fprintf(w, "data: %s\n\n", message)
			w.(http.Flusher).Flush() // 立即刷新到客户端
		}
	}
}

func main() {
	http.HandleFunc("/events", sseHandler)
	log.Println("SSE服务器启动在 :8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

关键点说明:

  1. 响应头设置:必须设置Content-Type: text/event-stream和其他相关头信息
  2. 数据格式:每条消息以data:开头,以两个换行符\n\n结束
  3. 连接保持:使用Connection: keep-alive保持长连接
  4. 实时刷新:调用Flush()立即将数据发送到客户端

客户端使用示例(JavaScript):

const eventSource = new EventSource('http://localhost:8080/events');
eventSource.onmessage = function(event) {
    console.log('收到消息:', event.data);
};
eventSource.onerror = function(event) {
    console.error('连接错误:', event);
};

注意事项:

  • 默认情况下,浏览器对SSE连接数有限制(通常每个域名6个)
  • 如果需要更复杂的控制,可以考虑使用WebSocket
  • 生产环境中需要添加错误处理和重连机制

这个实现可以满足基本的SSE推送需求,根据实际场景可以扩展更多功能。

回到顶部