启动Go HTTP服务器,做一些事情,然后在任务完成后将其关闭

我正在从 CLI 应用程序设置 OAuth2 流,我正在处理。我需要为提供商创建一个临时HTTP服务器以发送回调,例如localhost:8080/callback

一旦提供商发送了我需要的详细信息,我希望能够关闭HTTP服务器,只是为了保持一切干净。我想我正在寻找的是例程和等待组,但我对这个领域仍然很陌生。

这就是我到目前为止所拥有的。我已经编辑了将用户发送到提供程序的部分,因为我的主要问题只是如何在捕获变量后关闭HTTP服务器。token

  1. 服务器启动

  2. 将用户定向到提供程序站点上的授权 URL

  3. 用户批准请求

  4. 提供程序将用户定向回localhost:8080/callback

  5. URL仅包含客户端参数,因此我必须使用服务器HTML来捕获值并将其发送回服务器

  6. 服务器接收令牌,然后可以关闭

package main


import (

    "fmt"

    "log"

    "net/http"

    "sync"

)


func main() {

    // Start local HTTP serevr to listen for response

    serverDone := &sync.WaitGroup{}

    serverDone.Add(1)

    Start(serverDone)


    // ... Process to start OAuth2 flow

    // User is directed to provider website

    // User approves

    // Provider direct user back to localhost/callback

    

    serverDone.Wait()

}


func Start(wg *sync.WaitGroup) {


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

    http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {

        token := r.URL.Query().Get("token")

        if token != "" {

            fmt.Println("Found Token:", token)

            // Shut down server here

        } else {

            // Server HTML page to fetch token and return to server at /callback

        }

    })


    go func() {

        // let main know we are done cleaning up

        defer wg.Done()


        // ErrServerClosed on graceful close

        if err := srv.ListenAndServe(); err != http.ErrServerClosed {

            log.Fatalf("ListenAndServe(): %v", err)

        }

    }()

}


墨色风雨
浏览 119回答 1
1回答

慕妹3242003

用:var ctxShutdown, cancel = context.WithCancel(context.Background())然后:cancel() // to say sorry, above.// graceful-shutdownerr := srv.Shutdown(context.Background())试试这个:package mainimport (&nbsp; &nbsp; "context"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "log"&nbsp; &nbsp; "net/http"&nbsp; &nbsp; "sync")func main() {&nbsp; &nbsp; serverDone := &sync.WaitGroup{}&nbsp; &nbsp; serverDone.Add(1)&nbsp; &nbsp; Start(serverDone)&nbsp; &nbsp; serverDone.Wait()&nbsp; &nbsp; fmt.Println("Done that.")}var ctxShutdown, cancel = context.WithCancel(context.Background())func Start(wg *sync.WaitGroup) {&nbsp; &nbsp; srv := &http.Server{Addr: ":8080"}&nbsp; &nbsp; http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-ctxShutdown.Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Sorry: Shuting down ...")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; token := r.URL.Query().Get("token")&nbsp; &nbsp; &nbsp; &nbsp; if token != "" {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Found Token:", token)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Shuting down ...")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Shut down server here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cancel() // to say sorry, above.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // graceful-shutdown&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; err := srv.Shutdown(context.Background())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Println("server.Shutdown:", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintln(w, "Hi") // Server HTML page to fetch token and return to server at /callback&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; })&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; if err := srv.ListenAndServe(); err != http.ErrServerClosed {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Fatalf("ListenAndServe(): %v", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Bye.")&nbsp; &nbsp; }()}运行并打开 http://127.0.0.1:8080/callback?token=2输出:Found Token: 2Shuting down ...Bye.Done that.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go