我正在尝试将node.js HTTP服务器转换为Go。这就是我想要发生的事情:
我有一个间歇生成的资源(比如每隔一秒左右),我希望所有对此资源的请求都等到下一次生成。这样客户端可以轮询并保证只获取最新资源。我正在使用web.go来消除运行HTTP服务器的许多复杂性。
以下是我的代码的简要版本:
package main
import (
"time"
"web"
"fmt"
vector "container/vector"
)
var listeners vector.Vector;
func resource (ctx *web.Context) {
c := make(chan int)
listeners.Push(c)
go func() {
<-c
go func() {
ctx.WriteString("Cool")
fmt.Println("Wrote something")
}()
}()
}
func resourceLoop() {
time.Sleep(5 * 1000 * 1000000) // sleep for 5 seconds
for ; listeners.Len() > 0 ; {
c := listeners.Pop().(chan int)
c <- 1
}
go resourceLoop()
}
func main() {
web.Get("/resource", resource)
go resourceLoop()
web.Run("localhost:4000")
}
我希望有一个Context.End()或类似的函数,但它似乎没有。我阅读了web.go的源代码,但我无法弄清楚它在哪里结束响应(web.go:268是我的resource()被调用的地方)。在node.js中,这是微不足道的,您可以调用ServerResponse.end()。
当我在Chrome中运行脚本时终止服务器时,我得到了这个输出(似乎是正确的,除了响应没有结束):
4
Cool
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Date: Sat, 16 Apr 2011 00:37:58 GMT
Server: web.go
Transfer-Encoding: chunked
0
这是web.go框架的问题还是我做错了什么?如果这是框架的问题,我会向他提出问题。
我是Go的新手,所以我可能会完全错误。
答案 0 :(得分:3)
我从未使用过web.go,但似乎你的例子太复杂了。为什么你需要一个goroutine来产生goroutine?我认为框架本身会处理并发性,只需写下来:
func resource (ctx *web.Context, val string) string {
c := make(chan int)
listeners.Push(c)
<-c
return "Cool"
}
否则,看起来它正在完全按照您的意愿行事,如果您真的完成了它,您只需要关闭连接:
ctx.Close()