我是 Go 新手,遇到以下问题。我试图简化它:
我有一个服务器,其中有一个全局变量myvar
。所有用户都可以 POST 端点 /step1
并将一些数据保存在变量中,这些数据可以使用第二个端点 /step2
通过 GET 进行检索。在这 2 次调用之间,该用户的 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)
}
最佳答案
多个 goroutine 同时处理请求。这意味着如果它们读/写相同的变量,则必须同步对该变量的访问。
接下来,如果您希望每个用户都有不同的数据实例,则可以使用映射,将用户 ID 或名称映射到数据结构。
假设数据结构是一个结构体,例如:
type customData struct {
Field1 string
Field2 int
// Whatever fields you need
}
map 为每个用户保留一个:
var userDataMap = map[string]customData{}
您可以使用sync.RWMutex
用于在从 Goroutine 读取/写入映射时保护映射:
var mu = &sync.RWMutex{}
并使用上面的互斥体同步访问 map :
func Get(user string) customData {
mu.RLock()
defer mu.RUnlock()
return userDataMap[user]
}
func Set(user string, data customData) {
mu.Lock()
userDataMap[user] = data
mu.Unlock()
}
另一个更复杂的解决方案是使用服务器端 HTTP session 。详情见Go session variables?
关于go - 具有多个用户的服务器实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44070323/