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

Go 如何在Gin框架中添加后回调,go,go-gin,Go,Go Gin,我需要使用os退出应用程序。在HTTP请求完全完成后退出(0)。我的应用程序询问另一台服务器是否需要升级,因此我需要退出以执行重新启动后的自我升级,但我不想中断当前的HTTP请求 当我在c.Next()之后或在处理程序函数末尾尝试退出中间件时,浏览器给出错误:localhost没有发送任何数据 如何做到这一点?正如您所说,您的程序将在HTTP连接完全完成之前终止-您需要等待HTTP事务完成,然后退出。幸运的是,由于Go 1.8http.Server有一个可以满足您需要的功能 关机会正常关闭服务器

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

当我在
c.Next()
之后或在处理程序函数末尾尝试退出中间件时,浏览器给出错误:
localhost没有发送任何数据


如何做到这一点?

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

关机会正常关闭服务器,而不会中断任何活动连接。关机的工作原理是先关闭所有打开的侦听器,然后关闭所有空闲连接,然后无限期地等待连接返回空闲状态,然后关机

因此,一般做法是:

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
exitChan:=make(chan结构{})
//以某种方式将exitChan的引用获取给您的处理程序
h:=&http.Server{
//你的配置
}
go func(){
h、 ListenAndServe()//在goroutine中运行服务器,以免阻塞
}()

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

主程序包
进口(
“上下文”
“日志”
“net/http”
“操作系统”
“操作系统/信号”
“时间”
“github.com/gin gonic/gin”
)
func main(){
路由器:=gin.Default()
router.GET(“/”,func(c*gin.Context){
时间。睡眠(5*时间。秒)
c、 字符串(http.StatusOK,“欢迎登录服务器”)
})
srv:=&http.Server{
地址:“:8080”,
处理程序:路由器,
}
go func(){
//服务连接
如果err:=srv.ListenAndServe();err!=nil&&err!=http.ErrServerClosed{
log.Fatalf(“侦听:%s\n”,错误)
}
}()
//等待中断信号正常关闭服务器
//超时5秒。
退出:=接通(切换操作信号)
信号通知(退出,操作系统中断)

是的,它是有效的。但是需要一些额外的线来让它与GIN一起工作。也没有5秒超时,它立即退出,这很好。同时考虑一下提供代码的解释,以提高你的答案的长期价值。
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")
}