如何在Golang中使用gin-gonic服务器编写流API?尝试使用c.Stream但不起作用。

huangapple go评论87阅读模式
英文:

How to write a stream API using gin-gonic server in golang? Tried c.Stream didnt work

问题

我想在Go语言中使用gin-gonic服务器创建一个流式API。

func StreamData(c *gin.Context) {
    chanStream := make(chan int, 10)
    go func() {
        for i := 0; i < 5; i++ {
            chanStream <- i
            time.Sleep(time.Second * 1)
        }
    }()
    c.Stream(func(w io.Writer) bool {
        c.SSEvent("message", <-chanStream)
        return true
    })
}

router.GET("/stream", controller.StreamData)

但是当我尝试访问这个端点时,它就会卡住,没有响应返回。
有人使用过流式函数吗?他/她能指出我可能犯的错误吗?谢谢!

英文:

I wanted to create one streaming API using gin-gonic server in golang.

func StreamData(c *gin.Context) {
	chanStream := make(chan int, 10)
	go func() {for i := 0; i &lt; 5; i++ {
		chanStream &lt;- i
		time.Sleep(time.Second * 1)
	}}()
	c.Stream(func(w io.Writer) bool {
		c.SSEvent(&quot;message&quot;, &lt;-chanStream)
		return true
	})
}

router.GET(&quot;/stream&quot;, controller.StreamData)

But when I am trying to hit the endpoint, it just stucks and no response comes.
Has someone used the stream function so that he/she can point the mistake which I might be doing. Thanks!

答案1

得分: 20

你应该在流结束时返回false,并关闭chan。

package main

import (
	"io"
	"time"

	"github.com/gin-gonic/contrib/static"
	"github.com/gin-gonic/gin"
	"github.com/mattn/go-colorable"
)

func main() {
	gin.DefaultWriter = colorable.NewColorableStderr()
	r := gin.Default()
	r.GET("/stream", func(c *gin.Context) {
		chanStream := make(chan int, 10)
		go func() {
			defer close(chanStream)
			for i := 0; i < 5; i++ {
				chanStream <- i
				time.Sleep(time.Second * 1)
			}
		}()
		c.Stream(func(w io.Writer) bool {
			if msg, ok := <-chanStream; ok {
				c.SSEvent("message", msg)
				return true
			}
			return false
		})
	})
	r.Use(static.Serve("/", static.LocalFile("./public", true)))
	r.Run()
}

附加内容

客户端代码应为:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
var stream = new EventSource("/stream");
stream.addEventListener("message", function(e){
	console.log(e.data);
});
</script>    
</body>
</html>
英文:

You should return false if the stream ended. And close the chan.

package main

import (
	&quot;io&quot;
	&quot;time&quot;

	&quot;github.com/gin-gonic/contrib/static&quot;
	&quot;github.com/gin-gonic/gin&quot;
	&quot;github.com/mattn/go-colorable&quot;
)

func main() {
	gin.DefaultWriter = colorable.NewColorableStderr()
	r := gin.Default()
	r.GET(&quot;/stream&quot;, func(c *gin.Context) {
		chanStream := make(chan int, 10)
		go func() {
			defer close(chanStream)
			for i := 0; i &lt; 5; i++ {
				chanStream &lt;- i
				time.Sleep(time.Second * 1)
			}
		}()
		c.Stream(func(w io.Writer) bool {
			if msg, ok := &lt;-chanStream; ok {
				c.SSEvent(&quot;message&quot;, msg)
				return true
			}
			return false
		})
	})
	r.Use(static.Serve(&quot;/&quot;, static.LocalFile(&quot;./public&quot;, true)))
	r.Run()
}

Additional

Client code should be:

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script&gt;
var stream = new EventSource(&quot;/stream&quot;);
stream.addEventListener(&quot;message&quot;, function(e){
	console.log(e.data);
});
&lt;/script&gt;    
&lt;/body&gt;
&lt;/html&gt;

huangapple
  • 本文由 发表于 2017年6月29日 20:31:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/44825244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定