Golang:异步HTTP服务器中的共享通信 [英] Golang: Shared communication in async http server
问题描述
Http请求'a'进来,一个操作根据POST请求在这个请求中启动(在帖子或网址中添加某种唯一标识符)。由'a'开始的异步过程将在请求'a'仍然打开的情况下以原始唯一标识符(请求'b')响应回同一服务器。我希望根据请求的'b'响应回应请求'a'的响应。
虽然它是可能的做法是使用频道,
我希望有一个由互斥体保护的散列(地图),
,因为在这种情况下更简单。
package main
import(
fmt
net / http
同步
)
类型状态结构{
* sync.Mutex //继承锁定方法
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()//确保在离开函数
id:= req.URL.Query()。Get(id)后,会删除锁定//如果您需要其他类型,请参阅strconv软件包
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 =idvalue =42/>< br />
Val:< input name =val/>< br />
< input type =submitvalue =submit/>
< / form>
< / body>
< / html>`
func formHandler(rw http.ResponseWriter,req * http.Request){
rw.Write([] byte(form))
$ b //对于真正的路由,请看一下gorilla / mux包
func处理函数(rw http.ResponseWriter,req * http.Request){
switch req。方法{
casePOST:
post(rw,req)
caseGET:
if req.URL.String()==/ form{
formHandler(rw,req)
return
}
get(rw,req)
}
}
func main( ){
fmt.Println(转到http:// localhost:8080 / form)
//这就是net / http包的默认webserver,但你可能是
//创建自定义服务器以及
err:= http.ListenAndServe(localhost:8080,http.HandlerFunc(handler))
if err!= nil {
fmt.Println(err)
}
}
Absolute beginner to golang other than writing a simple http server. I'm researching Go as a possibility for writing an async process. If you could please provide a quick sample of how this might be accomplished:
Http request 'a' comes in, an operation is started based on POST payload in this request (with some sort of unique identifier in post or url). The async process started by 'a' will respond back to same server with original unique identifier (request 'b') while request 'a' is still open. I'd like to communicate that response back to request 'a' based on request 'b' response.
Although it is possible to do this with channels, I would prefer a hash (map) that is protected by a mutex, since it is easier in this case.
To give you an idea and get you going:
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)
}
}
这篇关于Golang:异步HTTP服务器中的共享通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!