2011-04-16 47 views
1

我在尝试将我的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是我的资源()被调用的地方)。在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 

这是网络有问题.go框架还是我做错了什么?如果这个框架有问题,我会向他提出一个问题。

我对Go很新,所以我可能会对这个完全错误的。

回答

3

我从来没有用过web.go,但看起来你的例子太复杂了。你为什么需要一个门厅来建立一个门厅?我将承担框架本身会照顾并发的,只是这样写:

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

否则,它看起来是做你想要什么,你只需要关闭连接,如果你真的有做它:

ctx.Close() 
+0

哇......我想我是过度思考它。这似乎工作。非常感谢,我知道我做错了什么...... – tjameson 2011-04-16 02:57:55

+1

是的,我发现我做了几个阶段的发现编程。第一个是添加东西,直到代码工作。第二种是在工作时删除东西。 – Dustin 2011-04-17 18:16:57

+1

圣埃克苏佩里曾经说过。完美是实现的,而不是当没有更多东西需要添加时,而是什么时候没有东西可以带走。 – 2011-04-19 06:53:38