具有多个用户的服务器实例

时间:2017-05-19 12:36:41

标签: go concurrency server

我是Go的新手,我遇到了以下问题。我试图简化它: 我有一个服务器,例如有一个全局变量myvar。所有用户都可以POST端点/step1并在变量中保存一些数据,这些数据可以使用第二个端点/step2通过GET检索。在这两次调用之间,myvar的值不应该为该用户更改。

我想知道是否有办法为每个用户实例化这个过程,因为如果一个用户更改变量,我需要它,它不会影响其他用户。我不一定需要使用全局变量,它只是暴露我想要对端点做什么。

代码:

package main

import (
    "encoding/json"
    "net/http"

    "github.com/gorilla/mux"
    "github.com/rs/cors"

    "fmt"
)

type Test struct {
    test string `json:"test,omitempty"`
}

func main() {
    var myvar = "test"

    router := mux.NewRouter()

    router.HandleFunc("/step1", func(w http.ResponseWriter, r *http.Request) {
        var test Test
        _ = json.NewDecoder(r.Body).Decode(&test)
        myvar = test.test
    })

    router.HandleFunc("/step2", func(w http.ResponseWriter, r *http.Request) {
        fmt.Println(myvar)
    })

    c := cors.New(cors.Options{
        AllowedOrigins:   []string{"*"},
        AllowCredentials: true,
        AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE", "PATCH"},
        AllowedHeaders:   []string{"*"},
        ExposedHeaders:   []string{"*"},
    })

    handler := c.Handler(router)

    http.ListenAndServe(":8003", handler)
}

1 个答案:

答案 0 :(得分:4)

同时从多个goroutine提供请求。这意味着如果他们读/写相同的变量,则必须同步对此变量的访问。

接下来,如果您希望每个用户使用不同的数据实例,您可以使用地图,从用户ID或名称映射到数据结构。

我们假设数据结构是一个结构,例如:

type customData struct {
    Field1 string
    Field2 int
    // Whatever fields you need
}

每个用户持有一张地图:

var userDataMap = map[string]customData{}

您可以使用sync.RWMutex在从goroutine读取/写入地图时保护地图:

var mux = &sync.RWMutex{}

使用上面的互斥锁同步访问地图:

func Get(user string) customData {
    mux.RLock()
    defer mux.RUnlock()
    return userDataMap[user]
}

func Set(user string, data customData) {
    mux.Lock()
    userDataMap[user] = data
    mux.Unlock()
}

另一个更复杂的解决方案是使用服务器端HTTP会话。有关详细信息,请参阅Go session variables?