我们都知道,想实现浏览器和服务器互相推送消息,可以使用 websocket 协议。
但如果只想实现浏览器推送消息给客户端,我们还可以选择 SSE 协议,它其实是基于 HTTP 的一种协议。
SSE,服务器发送事件(Server-sent events
)
至于它是怎么基于 HTTP 来实现的呢?说理论太枯燥,我们直接看 Go 代码:
(要了解理论的去看我引用的文章)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| package main
import ( "fmt" "github.com/gin-gonic/gin" "gopkg.in/antage/eventsource.v1" "log" "net/http" )
func main() { es := eventsource.New(nil, nil) defer es.Close() r := gin.Default()
{ r.GET("/events", esSSE) r.Run(":8080") } }
func esSSE(c *gin.Context) { w := c.Writer
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", "*")
_, ok := w.(http.Flusher)
if !ok { log.Panic("server not support") }
_, err := fmt.Fprintf(w, "data: %s\n\n", "dsdf") if err != nil { return } }
|
这里的核心代码就在于 Header 的设置,比如 w.Header().Set("Content-Type", "text/event-stream")
只需要前端也做出相应的适配。SSE 其实就完成了。
这里我顺便也贴一个纯 html 的 Demo 吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <!DOCTYPE html> <html> <head> <title>SSE test</title> <script type="text/javascript"> window.addEventListener("DOMContentLoaded", function () { var evsrc = new EventSource("http://localhost:8080/events"); evsrc.onmessage = function (ev) { document.getElementById("log") .insertAdjacentHTML("beforeend", "<li>" + ev.data + "</li>"); } 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>
|