在go语言中实现SSE方式、场景及注意事项

sse简单的来说就是服务器主动向客户端推送数据的一种技术,它是单向的,也就是说客户端是不能向服务器发送数据的。sse适用于消息推送,监控等只需要服务器推送数据的场景中,下面是使用go来实现一下sse方式。

示例代码:

1.服务端代码

package main

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

type SSE struct {
}

func (sse *SSE) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
   flusher, ok := rw.(http.Flusher)
   if !ok {
      http.Error(rw, "Streaming unsupported!", http.StatusInternalServerError)
      return
   }
   
   rw.Header().Set("Content-Type", "text/event-stream")
   rw.Header().Set("Cache-Control", "no-cache")
   rw.Header().Set("Connection", "keep-alive")
   rw.Header().Set("Access-Control-Allow-Origin", "*")
   
   for {
      select {
      case <-req.Context().Done():
         fmt.Println("req done...")
         return
      case <-time.After(500 * time.Millisecond):
         // 返回数据包含id、event(非必须)、data,结尾必须使用\n\n
         fmt.Fprintf(rw, "id: %d\nevent: ping \ndata: %d\n\n", time.Now().Unix(), time.Now().Unix())
         flusher.Flush()
      }
   }
}

func SendData(data chan int64) chan int64 {
   for {
      data <- time.Now().Unix()
      time.Sleep(time.Second * time.Duration(2))
   }
}

func main() {
   http.Handle("/sse", &SSE{})
   http.ListenAndServe(":8080", nil)
}


2.客服端代码

    const source = new EventSource('http://127.0.0.1:8080/sse');
    source.onopen = () => {
        console.log('链接成功');
    };
    source.addEventListener("ping",function(res){
         console.log('获得数据:' + res.data);
    })
    source.onerror = (err) => {
        console.log(err);
    };

注意事项:

如果服务器端提供了event参数 (完整的消息包含 id、data、event),那么客户端就需要使用addEventListener显式监听这个事件,才会正常获取消息,否则事件不会触发。

如果服务器端没有提供 event 参数,只有 id、data 等,

可以使用onmessage回调监听消息:


场景一:

服务器有event参数,并且定义了一个叫ping的具体事件

const source = new EventSource('http://127.0.0.1:8080/sse');
source.onopen = () => {
    console.log('链接成功');
};
source.addEventListener("ping",function(res){
     console.log('获得的数据是:' + res.data);
})
source.onerror = (err) => {
    console.log(err);
};

场景二:

服务器返回的数据不包含event

const source = new EventSource('http://127.0.0.1:8080/sse');
  source.onopen = () => {
      console.log('链接成功');
  };
  source.onmessage(function(res){
       console.log('获得的数据是:' + res.data);
  })
  source.onerror = (err) => {
      console.log(err);
  };

相关文章