Golang:异步HTTP服务器中的共享通信 [英] Golang: Shared communication in async http server

查看:138
本文介绍了Golang:异步HTTP服务器中的共享通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除了编写一个简单的http服务器之外,绝对的初学者是golang。我正在研究Go作为编写异步过程的可能性。如果您可以请提供一个快速样例来说明如何实现:



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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆