Go 参加各种活动
我正在尝试为Gin服务器制作中间件,以便在单个请求期间处理事件,因为我需要来自上下文的IP地址之类的东西,而不是传递整个上下文。我宁愿传递我的侦听器,这使我的方法不依赖于Go 参加各种活动,go,go-gin,Go,Go Gin,我正在尝试为Gin服务器制作中间件,以便在单个请求期间处理事件,因为我需要来自上下文的IP地址之类的东西,而不是传递整个上下文。我宁愿传递我的侦听器,这使我的方法不依赖于Gin.context 我设置了一个服务器 func main() { router := gin.New() router.Use(gin.Recovery()) api := router.Group("api", middleware()) { api.G
Gin.context
我设置了一个服务器
func main() {
router := gin.New()
router.Use(gin.Recovery())
api := router.Group("api", middleware())
{
api.GET("test/:id", endpoint)
}
router.Run("localhost:8080")
}
制作了一个中间件
func middleware() gin.HandlerFunc {
return func(c *gin.Context) {
listener := make(chan int)
c.Set("EventListener", listener)
go func() {
select {
case <-listener:
fmt.Println("event called")
default:
fmt.Println("default")
}
}()
c.Next()
}
}
和doSomething
函数来显示以后没有使用上下文
func doSomething(listener chan int, id int) {
if id == 1 {
fmt.Println("ERROR: cause event and exit")
listener <- int(id)
return
}
if id == 2 {
fmt.Println("WARN: cause event but continue")
listener <- int(id)
}
fmt.Println("OK: everything is fine")
}
但这个循环的停止条件是什么呢
我知道有类似于c.Done()
的东西,它是chan
,但我不知道如何在我的情况下使用它,因为我可以像
for {
select {
case <-listener:
fmt.Println("event called")
}
}
for {
select {
case <-listener:
fmt.Println("event called")
case <-c.Done():
return
}
}
用于{
挑选{
case我发现还有c.Request.Context().Done()
现在可以工作了,停止goroutine
并允许处理多个事件
go func() {
for {
select {
case <-listener:
fmt.Println("event called")
case <-c.Request.Context().Done():
return
}
}
}()
go func(){
为了{
挑选{
case将c
作为函数文本的参数传递,或者直接在函数文本中引用它,因为函数文本的周围块确实包含c
。这不是一个解决方案,因为它不像文档中描述的那样做。有点奇怪,但希望有c.Request.Context().Done()
我认为我们应该在goroutines中使用Gin Context的克隆,如中所建议的
go func() {
for {
select {
case <-listener:
fmt.Println("event called")
case <-c.Request.Context().Done():
return
}
}
}()