英文:
Golang Map of http.ResponseWriters
问题
我正在尝试创建一个存储http.ResponseWriter的映射,以便稍后在单独的线程完成相关计算后写入它们。
在我的主函数中,我定义了这个映射如下:
jobs := make(map[uint32]http.ResponseWriter)
然后我将这个映射传递给一个处理函数,代码如下:
r.HandleFunc("/api/{type}/{arg1}", func(w http.ResponseWriter, r *http.Request) {
typ, _ := strconv.Atoi(mux.Vars(r)["type"])
AddReqQueue(w, ReqQueue, typ, mux.Vars(r)["arg1"], jobs, ids)
}).Methods("get")
然后我处理请求并将其添加到一个通道中:
func AddReqQueue(w http.ResponseWriter, ReqQueue chan mssg.WorkReq, typ int, arg1 string, jobs map[uint32]http.ResponseWriter, ids []uint32) {
var id uint32
id, ids = ids[0], ids[1:] // 获取一个空闲的工作ID
jobs[id] = w
fmt.Println("Adding req to queue")
ReqQueue <- mssg.WorkReq{Type: uint8(typ), Arg1: arg1, WId: id}
}
在这个函数内部,我已经测试过并且能够向ResponseWriter写入数据,但是稍后当我尝试在以下函数中使用映射时:
func SendResp(RespQueue chan mssg.WorkResp, jobs map[uint32]http.ResponseWriter) {
for {
resp := <-RespQueue
jobs[resp.WId].Header().Set("Content-Type", "text/plain")
_, err := jobs[resp.WId].Write(resp.Data) // 错误发生在这里
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
}
}
}
它不起作用。无论我如何预先设置头部或尝试写入(甚至只是一个简单的硬编码字符串),我都会得到一个错误:
Conn.Write wrote more than the declared Content-Length
我知道我正在访问映射中的正确结构,只是好像ReponseWriter
已经失去了上下文或被破坏了,而且我知道头部实际上并不重要,因为这是我第一次调用Write()
,所以它应该为我创建头部。
英文:
I'm trying to create a map that stores http.ResponseWriters so that I can write to them later, after a separate thread has done the relevant computation.
The map is defined in my main as follow:
jobs := make(map[uint32]http.ResponseWriter)
I then pass this map to a handle function like so:
r.HandleFunc("/api/{type}/{arg1}", func(w http.ResponseWriter, r *http.Request) {
typ, _ := strconv.Atoi(mux.Vars(r)["type"])
AddReqQueue(w, ReqQueue, typ, mux.Vars(r)["arg1"], jobs, ids)
}).Methods("get")
After that I process the reuqeuest and add it to a channel:
func AddReqQueue(w http.ResponseWriter, ReqQueue chan mssg.WorkReq, typ int, arg1 string, jobs map[uint32]http.ResponseWriter, ids []uint32) {
var id uint32
id, ids = ids[0], ids[1:] // get a free work id
jobs[id] = w
fmt.Println("Adding req to queue")
ReqQueue <- mssg.WorkReq{Type: uint8(typ), Arg1: arg1, WId: id}
}
Inside this function I have tested and am able to write data to the ReponseWriter, however later when I try to use the map in:
func SendResp(RespQueue chan mssg.WorkResp, jobs map[uint32]http.ResponseWriter) {
for {
resp := <-RespQueue
jobs[resp.WId].Header().Set("Content-Type", "text/plain")
_, err := jobs[resp.WId].Write(resp.Data) // ERROR IS COMING FROM HERE
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
}
}
}
It doesn't work. No matter what I pre-set the header too or try to write (even just a simple string I hardcoded) I get a err of
Conn.Write wrote more than the declared Content-Length
I know I'm accessing the right struct in the map, it just seems as if the ReponseWriter
has gone out of context or been corrupted, also i know that the headers shouldn't really matter since it is the first time I am calling Write()
and therefore it should create the headers for me.
答案1
得分: 2
@elithrar是正确的。我没有意识到在处理程序退出后,http.ResponseWriter对象会变为无效。如果我只是强制处理程序等待,它就可以正常工作。
英文:
@elithrar was correct. I wasn't aware that the http.ResponseWriter object became invalid after the handler exited. If I just force my handler to wait, it works fine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论