首页  >  文章  >  后端开发  >  如何在响应后正常关闭 HTTP 服务器?

如何在响应后正常关闭 HTTP 服务器?

Linda Hamilton
Linda Hamilton原创
2024-10-31 04:19:30498浏览

How to Gracefully Shut Down an HTTP Server After a Response?

响应后正常关闭 HTTP 服务器

问题

使用本地 HTTP 服务器捕获 OAuth 访问令牌以进行 Instagram API 集成时,向用户显示令牌后需要关闭服务器。但是,尝试使用 srv.Shutdown() 手动终止服务器会导致错误:

Httpserver: ListenAndServe() error: http: Server closed
http: panic serving [::1]:61793: runtime error: invalid memory address or nil pointer dereference

分析

发生错误是因为在 showTokenToUser 期间 HTTP 服务器仍在处理其他请求handler 正在尝试将其关闭。

解决方案

完成回调请求后优雅地关闭 HTTP 服务器:

1.使用 Context.WithCancel()

使用 context.WithCancel() 创建可以手动取消的上下文。启动时将此上下文传递给 HTTP 服务器。

2.优雅地关闭服务器

在回调处理程序showTokenToUser中,调用srv.Shutdown(ctx)来优雅地关闭服务器。 ctx 是传递给服务器的已取消上下文。

代码

<code class="go">package main

import (
    "context"
    "io"
    "log"
    "net/http"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    http.HandleFunc("/instagram/callback", func(w http.ResponseWriter, r *http.Request) {
        showTokenToUser(w, r, ctx)
    })

    srv := &http.Server{Addr: ":8000"}
    go func() {
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Printf("httpserver: ListenAndServe() error: %s", err)
        }
    }()

    <-ctx.Done()

    // Gracefully shut down the server
    if err := srv.Shutdown(context.Background()); err != nil && err != context.Canceled {
        log.Println(err)
    }
}

func showTokenToUser(w http.ResponseWriter, r *http.Request, ctx context.Context) {
    io.WriteString(w, fmt.Sprintf("Your access token is: %v", r.URL.Query().Get("code")))
    cancel()
}</code>

此解决方案可确保 HTTP 服务器在回调请求完成后正常关闭,不会导致任何错误或中断持续连接。

以上是如何在响应后正常关闭 HTTP 服务器?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn