We can easily implement HTTP streaming data return.

Framework version < v2.4

If the current framework version is less than v2.4 final version (not beta version), use the following method to return (native standard library writing).

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/net/ghttp"
  8. )
  9. func main() {
  10. s := g.Server()
  11. s.BindHandler("/", func(r *ghttp.Request) {
  12. rw := r.Response.RawWriter()
  13. flusher, ok := rw.(http.Flusher)
  14. if !ok {
  15. http.Error(rw, "Streaming unsupported!", http.StatusInternalServerError)
  16. return
  17. }
  18. r.Response.Header().Set("Content-Type", "text/event-stream")
  19. r.Response.Header().Set("Cache-Control", "no-cache")
  20. r.Response.Header().Set("Connection", "keep-alive")
  21. for i := 0; i < 100; i++ {
  22. _, err := fmt.Fprintf(rw, "data: %d\n", i)
  23. if err != nil {
  24. panic(err)
  25. }
  26. flusher.Flush()
  27. time.Sleep(time.Millisecond * 200)
  28. }
  29. })
  30. s.SetPort(8999)
  31. s.Run()
  32. }

Framework version >= v2.4

Because the above operation is somewhat cumbersome, operational improvements were made in this version and above. If the current framework version is v2.4 final version (not beta version) or later, you can quickly implement streaming data return using the following method.

  1. package main
  2. import (
  3. "time"
  4. "github.com/gogf/gf/v2/frame/g"
  5. "github.com/gogf/gf/v2/net/ghttp"
  6. )
  7. func main() {
  8. s := g.Server()
  9. s.BindHandler("/", func(r *ghttp.Request) {
  10. r.Response.Header().Set("Content-Type", "text/event-stream")
  11. r.Response.Header().Set("Cache-Control", "no-cache")
  12. r.Response.Header().Set("Connection", "keep-alive")
  13. for i := 0; i < 100; i++ {
  14. r.Response.Writefln("data: %d", i)
  15. r.Response.Flush()
  16. time.Sleep(time.Millisecond * 200)
  17. }
  18. })
  19. s.SetPort(8999)
  20. s.Run()
  21. }

Example Result

After execution, visiting http://127.0.0.1:8999/ shows data continuously returned to the caller in a streaming manner.

Response - Streaming - 图1

Precautions

  • If used in a controller, the Request object can be acquired through the g.RequestFromCtx(ctx) method.
  • If there is a middleware for pre-unified input and output processing, please place this method outside the middleware scope or use the r.ExitAll() method to exit middleware control.

References

Server-Sent Events (SSE)