同时回应多个请求时出现问题

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

Trouble responding to multiple requests at the same time

问题

我正在尝试将我的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) // 睡眠5秒
    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还不太熟悉,所以我可能完全弄错了。

英文:

I am trying to convert my node.js HTTP server to Go. Here's what I want to happen:

I have a resource that gets generated intermittently (say every second or so), and I want all requests for this resource to wait until the next time it is generated. This way clients can poll and be guaranteed to get only the up-to-date resource. I am using web.go to remove a lot of the complexity of running an HTTP server.

Here is a brief version of my code:

package main

import (
    &quot;time&quot;
    &quot;web&quot;
    &quot;fmt&quot;
    vector &quot;container/vector&quot;
)

var listeners vector.Vector;

func resource (ctx *web.Context) {
    c := make(chan int)
    listeners.Push(c)
    go func() {
        &lt;-c
        go func() {
            ctx.WriteString(&quot;Cool&quot;)
            fmt.Println(&quot;Wrote something&quot;)
        }()
    }()
}

func resourceLoop() {
    time.Sleep(5 * 1000 * 1000000) // sleep for 5 seconds
    for ; listeners.Len() &gt; 0 ; {
        c := listeners.Pop().(chan int)
        c &lt;- 1
    }

    go resourceLoop()
}

func main() {
    web.Get(&quot;/resource&quot;, resource)

    go resourceLoop()

    web.Run(&quot;localhost:4000&quot;)
}

I would expect there to be a Context.End() or similar function, but it doesn't seem to have one. I read the source for web.go, but I couldn't figure out where it was ending the response (web.go:268 is where my resource() is called). In node.js this is trivial, you can call a ServerResponse.end().

When I kill the server while running the script in Chrome, I get this output (seems to be correct, except that the response isn't ending):

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

Is this a problem with the web.go framework or am I doing something wrong? If it's a problem with the framework, I'll file an issue with him.

I'm pretty new to Go, so I could be going about this completely wrong.

答案1

得分: 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()
英文:

I've never used web.go, but it seems that your example is entirely too complicated. Why do you need a goroutine to spawn a goroutine? I would assume the framework itself would take care of concurrency and just write this:

func resource (ctx *web.Context, val string) string {
    c := make(chan int)
    listeners.Push(c)
    &lt;-c
    return &quot;Cool&quot;
}

Otherwise, it looks like it is doing exactly what you want and you just need to close the connection if you're truly done with it:

ctx.Close()

huangapple
  • 本文由 发表于 2011年4月16日 08:45:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/5683693.html
匿名

发表评论

匿名网友

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

确定