如何在 Gin 框架中添加后回调

How to add an after callback in Gin framework

我需要在 HTTP 请求完全完成后使用 os.Exit(0) 退出应用程序。我的应用程序询问另一台服务器是否需要升级,因此我需要退出以通过重启执行自我升级,但我不想中断当前的 HTTP 请求。

当我尝试在 c.Next() 之后或处理函数结束时退出中间件时,浏览器给出错误:localhost didn’t send any data.

如何做到这一点?

如您所说,您的程序在 HTTP 连接完全完成之前终止 - 您需要等待 HTTP 事务完成然后退出。幸运的是,因为 Go 1.8 http.Server 有一个 Shutdown method 可以满足你的需要。

Shutdown gracefully shuts down the server without interrupting any active connections. Shutdown works by first closing all open listeners, then closing all idle connections, and then waiting indefinitely for connections to return to idle and then shut down.

所以,一般的方法是:

exitChan := make(chan struct{})

// Get a reference to exitChan to your handlers somehow

h := &http.Server{
    // your config
}
go func(){
    h.ListenAndServe() // Run server in goroutine so as not to block
}()

<-exitChan // Block on channel
h.Shutdown(nil) // Shutdown cleanly with a timeout of 5 seconds

然后在您的 handler/middleware 中 exitChan <- struct{}{} 需要关机时。

另请参阅:

您可以在他们的 github 存储库中参考此示例:
graceful-shutdown

package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "time"

    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
        time.Sleep(5 * time.Second)
        c.String(http.StatusOK, "Welcome Gin Server")
    })

    srv := &http.Server{
        Addr:    ":8080",
        Handler: router,
    }

    go func() {
        // service connections
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Fatalf("listen: %s\n", err)
        }
    }()

    // Wait for interrupt signal to gracefully shutdown the server with
    // a timeout of 5 seconds.
    quit := make(chan os.Signal)
    signal.Notify(quit, os.Interrupt)
    <-quit
    log.Println("Shutdown Server ...")

    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    if err := srv.Shutdown(ctx); err != nil {
        log.Fatal("Server Shutdown:", err)
    }
    log.Println("Server exiting")
}