我想远程停止http服务器(我可以这样做),但是我也想收到一条消息,指示它在停止后已经停止了。那给我带来了一些问题。我可以找到的唯一解决方案如下所示,我认为这不是理想的解决方案。
任何人都可以提供更好的解决方案。问题是,除非我使用goroutine(如结尾“go func(){”所示),否则发送给客户端的最终消息将无法通过。
代码如下:
//*************
func stopServer(ohtWriter http.ResponseWriter, phtRequest *http.Request) {// Stop The Server
//*************
var iBytesSent int
var oOsError os.Error
var sErmes string
println("Stopping Server")
iBytesSent,oOsError = ohtWriter.Write([]byte("Message from server - server now stopped."))
if oOsError != nil {
sErmes = ". Error = " +oOsError.String()
} else {
sErmes = ". No error on write"
}
println("stopServer: Bytes sent = " +strconv.Itoa(iBytesSent) +sErmes)
ohtFlusher, tCanFlush := ohtWriter.(http.Flusher)
if tCanFlush {
ohtFlusher.Flush()
}
go func() {
time.Sleep(3e9)
os.Exit(0)
}()
}
最佳答案
是的,我认为,如果没有http包的支持,那么正常关闭是不可能的。这也许有点不那么令人信服,但在发出此请求时,它仍会猛击关闭正在运行的任何其他并发请求。也许尝试在Go issue tracker上提交功能请求。更好的是,打开http程序包,并添加一个正常的关闭方法和submit it。
编辑:我想如果您控制应用程序中的所有http.Handlers,则可以保留进行中的请求计数(使用适当的线程同步),然后将以下代码修改为:a)一旦“关闭”,拒绝新连接”,并且b)等待所有正在进行的请求完成后再关闭...
package main
import (
"http"
"os"
"io"
"log"
"strconv"
)
func main() {
http.HandleFunc("/", ServeHTTP)
http.ListenAndServe(":8081", nil)
}
const responseString = "Shutting down\n"
func ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("Content-Length", strconv.Itoa(len(responseString)))
io.WriteString(w, responseString)
f, canFlush := w.(http.Flusher)
if canFlush {
f.Flush()
}
conn, _, err := w.(http.Hijacker).Hijack()
if err != nil {
log.Fatalf("error while shutting down: %v", err)
}
conn.Close()
log.Println("Shutting down")
os.Exit(0)
}