2011-04-16 31 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