简单Go web服务器,在客户端中看不到响应
我正在学习Go,正在编写一个简单的web服务器,它使用一个通道来限制并发请求的数量。服务器在控制台上打印日志条目,显示它正在接收请求并处理它们,但是客户端浏览器不显示任何输出。我试着添加了一个反应作者,但没有帮助 作为一个傻瓜,我错过了什么?谢谢你的建议 代码如下:简单Go web服务器,在客户端中看不到响应,go,concurrency,webserver,Go,Concurrency,Webserver,我正在学习Go,正在编写一个简单的web服务器,它使用一个通道来限制并发请求的数量。服务器在控制台上打印日志条目,显示它正在接收请求并处理它们,但是客户端浏览器不显示任何输出。我试着添加了一个反应作者,但没有帮助 作为一个傻瓜,我错过了什么?谢谢你的建议 代码如下: package main import ( "fmt" "html" "net/http" "time" ) // define a type to be used with our reques
package main
import (
"fmt"
"html"
"net/http"
"time"
)
// define a type to be used with our request channel
type clientRequest struct {
r *http.Request
w http.ResponseWriter
}
const (
MaxRequests int = 10
)
// the request channel, to limit the number of simultaneous requests being processed
var reqChannel chan *clientRequest
func init() {
reqChannel = make(chan *clientRequest, MaxRequests)
}
func main() {
// create the server's handler
var ServeMux = http.NewServeMux()
ServeMux.HandleFunc("/", serveHandler)
// start pool of request handlers, all reading from the same channel
for i := 0; i < MaxRequests; i++ {
go processRequest(i)
}
// create the server object
s := &http.Server{
Addr: ":8080",
Handler: ServeMux, // handler to invoke, http.DefaultServeMux if nil
ReadTimeout: 10 * time.Second, // maximum duration before timing out read of the request
WriteTimeout: 10 * time.Second, // maximum duration before timing out write of the response
MaxHeaderBytes: 1 << 20, // maximum size of request headers, 1048576 bytes
}
// start the server
err := s.ListenAndServe()
if err != nil {
fmt.Println("Server failed to start: ", err)
}
}
func serveHandler(w http.ResponseWriter, r *http.Request) {
var newRequest = new(clientRequest)
newRequest.r = r
newRequest.w = w
reqChannel <- newRequest // send the new request to the request channel
fmt.Printf("Sent request to reqChannel for URL: %q\n", html.EscapeString(r.URL.Path))
}
func processRequest(instanceNbr int) {
fmt.Printf("processRequest started for instance #%d\n", instanceNbr)
for theRequest := range reqChannel { // receive requests from the channel until it is closed
fmt.Printf("Got request from reqChannel for URL: %q\n", html.EscapeString(theRequest.r.URL.Path))
// xxx this isn't working:
fmt.Fprintf(theRequest.w, "processRequest instance #%d: URL is %q", instanceNbr, html.EscapeString(theRequest.r.URL.Path))
if f, ok := theRequest.w.(http.Flusher); ok {
f.Flush()
}
}
}
主程序包
进口(
“fmt”
“html”
“net/http”
“时间”
)
//定义要与我们的请求通道一起使用的类型
类型clientRequest结构{
r*http.Request
w http.ResponseWriter
}
常数(
MaxRequests int=10
)
//请求通道,用于限制正在处理的同时请求的数量
var reqChannel chan*clientRequest
func init(){
reqChannel=make(chan*clientRequest,MaxRequests)
}
func main(){
//创建服务器的处理程序
var ServeMux=http.NewServeMux()
ServeMux.HandleFunc(“/”,serveHandler)
//启动请求处理程序池,所有处理程序都从同一通道读取
对于i:=0;i MaxHeaderBytes:1服务器在serveHandler
返回时关闭响应
一种修复方法是阻止serveHandler
,直到请求得到处理。在下面的代码中,工作人员关闭done
以表示请求已完成。处理程序等待done
关闭
type clientRequest struct {
r *http.Request
w http.ResponseWriter
done chan struct{} // <-- add this line
}
func serveHandler(w http.ResponseWriter, r *http.Request) {
var newRequest = new(clientRequest)
newRequest.r = r
newRequest.w = w
newRequest.done = make(chan struct{})
reqChannel <- newRequest // send the new request to the request channel
fmt.Printf("Sent request to reqChannel for URL: %q\n", html.EscapeString(r.URL.Path))
<-newRequest.done // wait for worker goroutine to complete
}
func processRequest(instanceNbr int) {
fmt.Printf("processRequest started for instance #%d\n", instanceNbr)
for theRequest := range reqChannel { // receive requests from the channel until it is closed
fmt.Printf("Got request from reqChannel for URL: %q\n", html.EscapeString(theRequest.r.URL.Path))
fmt.Fprintf(theRequest.w, "processRequest instance #%d: URL is %q", instanceNbr, html.EscapeString(theRequest.r.URL.Path))
if f, ok := theRequest.w.(http.Flusher); ok {
f.Flush()
}
close(theRequest.done) // signal handler that request is complete
}
}
类型clientRequest结构{
r*http.Request
w http.ResponseWriter
done chan struct{}/您的答案如下:
ServeHTTP
返回后,请求完成
因此,您有一些解决方案:
- 放弃工作模式,在
serveHandler
- 在完成
serveHandler
之前,请等待请求得到完全处理,如下所示:
(在我的本地计算机上测试)
类型clientRequest结构{
r*http.Request
w http.ResponseWriter
已完成chan结构{}
}
func serveHandler(w http.ResponseWriter,r*http.Request){
var newRequest=new(clientRequest)
newRequest.r=r
newRequest.w=w
newRequest.done=make(chan结构{})
reqChannel感谢您在这方面的帮助。我正在研究关于并发性的有效Go部分中概述的概念。
var reqChannel = make(chan struct{}, MaxRequests)
func serveHandler(w http.ResponseWriter, r *http.Request) {
reqChannel <- struct{}{}
// handle the request
<-reqChannel
}
// HTTP cannot have multiple simultaneous active requests.[*]
// Until the server replies to this request, it can't read another,
// so we might as well run the handler in this goroutine.
// [*] Not strictly true: HTTP pipelining. We could let them all process
// in parallel even if their responses need to be serialized.
serverHandler{c.server}.ServeHTTP(w, w.req)
if c.hijacked() {
return
}
w.finishRequest()
type clientRequest struct {
r *http.Request
w http.ResponseWriter
done chan struct{}
}
func serveHandler(w http.ResponseWriter, r *http.Request) {
var newRequest = new(clientRequest)
newRequest.r = r
newRequest.w = w
newRequest.done = make(chan struct{})
reqChannel <- newRequest // send the new request to the request channel
fmt.Printf("Sent request to reqChannel for URL: %q\n", html.EscapeString(r.URL.Path))
<-newRequest.done // wait for the worker to finish
}
func processRequest(instanceNbr int) {
fmt.Printf("processRequest started for instance #%d\n", instanceNbr)
for theRequest := range reqChannel { // receive requests from the channel until it is closed
fmt.Printf("Got request from reqChannel for URL: %q\n", html.EscapeString(theRequest.r.URL.Path))
// xxx this isn't working:
fmt.Fprintf(theRequest.w, "processRequest instance #%d: URL is %q", instanceNbr, html.EscapeString(theRequest.r.URL.Path))
if f, ok := theRequest.w.(http.Flusher); ok {
f.Flush()
}
theRequest.done <- struct{}{}
}
}