Go 参加各种活动

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服务器制作中间件,以便在单个请求期间处理事件,因为我需要来自上下文的IP地址之类的东西,而不是传递整个上下文。我宁愿传递我的侦听器,这使我的方法不依赖于
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
        }
    }
}()