Golang的http.ResponseWriter的映射表

huangapple go评论81阅读模式
英文:

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(&quot;/api/{type}/{arg1}&quot;, func(w http.ResponseWriter, r *http.Request) {
	typ, _ := strconv.Atoi(mux.Vars(r)[&quot;type&quot;])
	AddReqQueue(w, ReqQueue, typ, mux.Vars(r)[&quot;arg1&quot;], jobs, ids)
}).Methods(&quot;get&quot;)

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(&quot;Adding req to queue&quot;)
	ReqQueue &lt;- 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 := &lt;-RespQueue
	jobs[resp.WId].Header().Set(&quot;Content-Type&quot;, &quot;text/plain&quot;)
	_, err := jobs[resp.WId].Write(resp.Data) // ERROR IS COMING FROM HERE
	if err != nil {
		fmt.Fprintf(os.Stderr, &quot;Fatal error: %s&quot;, 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.

huangapple
  • 本文由 发表于 2015年4月16日 11:14:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/29664720.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定