2013-07-26 45 views
2

除了編寫簡單的http服務器之外,絕對是golang的初學者。我正在研究Go作爲編寫異步過程的可能性。如果你可以請提供一個快速的樣例來說明這可能是如何實現的:Golang:異步HTTP服務器中的共享通信

Http請求'a'進來,一個操作是基於此請求中的POST有效負載啓動的(在post或url中有某種唯一標識符) 。由'a'開始的異步過程將在請求'a'仍然打開的情況下以原始唯一標識符(請求'b')響應回同一服務器。我希望根據請求'b'的迴應將這個回覆傳回請求'a'。

+0

我不是讓你編寫應用程序,我只是未能達到上這是否會通過共享內存或通道來完成,並如果通過渠道,基於唯一標識符將如何完成。據我瞭解,一個簡單的例子應該只是一個約5-10線? – kwolfe

+0

這是你要求的嗎?請求從客戶端到服務器進來。然後服務器將請求b發回客戶端。還是客戶發出第二個請求? – andybalholm

+0

頻道是做這件事的好方法。需要更多的細節,然後才能給出更多方向。 –

回答

6

儘管可以用頻道來做, 我更喜歡散列表(地圖),它受互斥鎖 保護,因爲在這種情況下更容易。

爲了給你一個想法,讓你去:

package main 

import (
    "fmt" 
    "net/http" 
    "sync" 
) 

type state struct { 
    *sync.Mutex // inherits locking methods 
    Vals map[string]string // map ids to values 
} 

var State = &state{&sync.Mutex{}, map[string]string{}} 

func get(rw http.ResponseWriter, req *http.Request) { 
    State.Lock() 
    defer State.Unlock() // ensure the lock is removed after leaving the the function 
    id := req.URL.Query().Get("id") // if you need other types, take a look at strconv package 
    val := State.Vals[id] 
    delete(State.Vals, id) 
    rw.Write([]byte("got: " + val)) 
} 

func post(rw http.ResponseWriter, req *http.Request) { 
    State.Lock() 
    defer State.Unlock() 
    id := req.FormValue("id") 
    State.Vals[id] = req.FormValue("val") 
    rw.Write([]byte("go to http://localhost:8080/?id=42")) 
} 

var form = `<html> 
    <body> 
     <form action="/" method="POST"> 
      ID: <input name="id" value="42" /><br /> 
      Val: <input name="val" /><br /> 
      <input type="submit" value="submit"/> 
     </form> 
    </body> 
</html>` 

func formHandler(rw http.ResponseWriter, req *http.Request) { 
    rw.Write([]byte(form)) 
} 

// for real routing take a look at gorilla/mux package 
func handler(rw http.ResponseWriter, req *http.Request) { 
    switch req.Method { 
    case "POST": 
     post(rw, req) 
    case "GET": 
     if req.URL.String() == "/form" { 
      formHandler(rw, req) 
      return 
     } 
     get(rw, req) 
    } 
} 

func main() { 
    fmt.Println("go to http://localhost:8080/form") 
    // thats the default webserver of the net/http package, but you may 
    // create custom servers as well 
    err := http.ListenAndServe("localhost:8080", http.HandlerFunc(handler)) 
    if err != nil { 
     fmt.Println(err) 
    } 
} 
+0

我得到req.PostForm undefined(類型* http.Request沒有字段或方法PostForm) – kwolfe

+0

奇怪的是它爲我工作(go1.1) ...但我更新了源代碼,它現在應該可以工作,並且有點短... – metakeule

+1

@kwolfe我查了一下 - 他們將字段從* http.Request.Form(go1.0)改爲* http.Request .FormValue(go1.1)。 但是,重寫的變體* http.Request.FormValue()適用於兩個版本。我強烈建議你升級到1.1.1,因爲在線文檔反映了該版本,並且速度更快。 – metakeule