在golang中每2秒触发一次服务器发送事件

问题描述 投票:0回答:1

我在 golang 中的服务器代码

package main

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

    "github.com/rs/cors"
)

func main() {
    mux := http.NewServeMux();

    mux.HandleFunc("/sse" , handleSse)

    c  := cors.New(cors.Options{
            AllowedOrigins:   []string{"*"},
            AllowedMethods:   []string{http.MethodGet, http.MethodPost,
                        http.MethodDelete , http.MethodPut},
            AllowCredentials: true,
        })

    handler := c.Handler(mux)

    log.Fatal(http.ListenAndServe(":6969" , handler))
}

func handleSse(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")

    f , ok := w.(http.Flusher);
    if !ok{
    http.Error( w , "SSE not supported" ,
        http.StatusBadRequest)
    return;
    }

    fmt.Fprintf(w,"data:%v\n\n","sample data");
    f.Flush();
}

客户端代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>SSE</title>
  </head>
  <body>
    SSE running
    <script>
    const event = new EventSource("http://localhost:6969/sse");
    event.onmessage = () =>{
        console.log("this dude is slow");
    };
    </script>
  </body>
</html>

我遇到的问题是,在网络选项卡中,新文本流或响应在 5.4 秒后出现。 我希望服务器每 2 秒发送一次响应 我已经在服务器代码中尝试了无限循环,这在一些教程中显示,但它不起作用

编辑: for 循环处理函数


func handleSse(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.WriteHeader(http.StatusOK)

    f , ok := w.(http.Flusher);
    if !ok{
    http.Error( w , "SSE not supported , IE6 bruh" ,
        http.StatusBadRequest)
    return;
    }

    for i := 0 ; i < 10 ; i++{
        fmt.Fprintln(w,"retry : 1000"); //This line also doesnot help
        fmt.Fprintf(w,"data :%v\n\n","Sorry");
        f.Flush();
    //time.Sleep(1 * time.Second) //This line increase delay to 25 secs
    }
}
javascript go backend server-sent-events
1个回答
0
投票

间距很重要 -

fmt.Fprintf(w,"data :%v\n\n","Sorry");
不起作用;它必须是
fmt.Fprintf(w, "data:%v\n\n", "Sorry")

以下是一个工作示例;它会发送 10 条消息,然后断开连接。因为它还设置了

retry: 10000
(在
10000ms
中重试,即
10s
),浏览器将在 10 秒后重新连接(并每秒接收另外 10 条消息)。请注意,我在消息中添加了时间戳(使输出更清晰,因为浏览器倾向于组合相同的输出行)。

package main

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

    "github.com/rs/cors"
)

func main() {
    mux := http.NewServeMux()

    mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
        w.Write([]byte(`<!DOCTYPE html>
<html lang="en">
  <head>
    <title>SSE</title>
  </head>
  <body>
    SSE running
    <script>
    const event = new EventSource("http://localhost:6969/sse");
    event.onmessage = () =>{
        console.log("this dude is slow");
    };
    </script>
  </body>
</html>
`))
    })

    mux.HandleFunc("/sse", handleSse)

    c := cors.New(cors.Options{
        AllowedOrigins: []string{"*"},
        AllowedMethods: []string{http.MethodGet, http.MethodPost,
            http.MethodDelete, http.MethodPut},
        AllowCredentials: true,
    })

    handler := c.Handler(mux)

    log.Fatal(http.ListenAndServe(":6969", handler))
}

func handleSse(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.WriteHeader(http.StatusOK)

    f, ok := w.(http.Flusher)
    if !ok {
        http.Error(w, "SSE not supported , IE6 bruh",
            http.StatusBadRequest)
        return
    }

    for i := 0; i < 10; i++ {
        fmt.Fprintln(w, "retry: 10000") // This means that after the connection drops the browser will wait 10 seconds before reconnecting
        fmt.Fprintf(w, "data:%v\n\n", "Sorry")
        f.Flush()
        time.Sleep(1 * time.Second) // This means a message will be sent every second (until 10 have been sent when the connection will drop)
    }
}

在真实的系统中,处理程序(在本例中为

handleSse
)很可能仅在写入时收到错误时退出,否则只要程序运行,它就会保持活动状态。这样的处理程序将从某个地方(可能通过通道)接收数据,并将其发送到浏览器。

© www.soinside.com 2019 - 2024. All rights reserved.