【问题标题】:http.ListenAndServe: Close when program exitshttp.ListenAndServe:程序退出时关闭
【发布时间】:2018-05-18 01:42:09
【问题描述】:

我想编写简单的 REST API 应用程序。我编写了处理 HTTP 请求的代码:

package main

import (
    "fmt"
    "log"
    "movies/dao"
    "net/http"

    "github.com/gorilla/mux"
)

var d = dao.MoviesDAO{}

// AllMoviesEndPoint show all movies
func AllMoviesEndPoint(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "not implemented yet")
}

func init() {
    d.Server = "127.0.0.1"
    d.Database = "movies"
}

func main() {
    //d.Connect()
    router := mux.NewRouter()
    router.HandleFunc("/movies", AllMoviesEndPoint).Methods("GET")

    go func() {
        if err := http.ListenAndServe(":3000", router); err != nil {
            log.Fatal(err)
        }
    }()
}

但是当我在调试器下运行这个 prgram 然后停止它时,socket 被绑定了,我可以从浏览器访问服务器,我不能再次运行程序,因为我收到一个错误listen tcp :3000: bind: address already in use

程序退出时如何关闭连接?

现在我需要kill -9 PID 我的服务器来启动新的调试会话。

【问题讨论】:

  • 您使用的是什么调试器,如何启动它,“停止它”是什么意思?
  • @Adrian,带有 VS Code 的 Delve 调试器。 “你所说的“停止”是什么意思?选择停止调试
  • 您的程序无效:http.ListenAndServe 调用块,但您开始运行它的 goroutine 与运行 main() 的 goroutine 不同步;当后者退出时,所有其他活动的 goroutine 都将被拆除。您的程序似乎以某种半途而废的状态挂在那里的事实可能是它被delve 调试的人工制品,但该程序仍然无效:如果您只是构建它并按原样运行,它会立即退出。
  • @typemoon 我认为你应该为你的 http 添加正常关闭,就像这里提到的:github.com/gorilla/mux#graceful-shutdown

标签: http go


【解决方案1】:

问题不在于调试器,问题在于您的代码。

当你写作时

go func() {
    if err := http.ListenAndServe(":3000", router); err != nil {
        log.Fatal(err)
    }
}()

您正在创建一个完全独立于主线程的新 goroutine。

这意味着你的 main 的执行是:

  1. 创建路由器
  2. 创建并执行一个 goroutine
  3. main 结束,返回并杀死所有子进程

没有什么让 main 等待 go 例程的执行和终止。

由于http.ListenAndServe 创建了一个无限期等待新连接的线程,因此您无需在 goroutine 中创建它。

因此,只需删除 go func() { 块就可以了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 2012-12-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多