有多个用户的服务器实例 [英] Server instances with multiple users
问题描述
我是Go的新手,我有以下问题。我试图简化它:
我有一个服务器,例如一个全局变量 myvar
。所有用户都可以在端点 / step1
上发布POST请求,并在变量中保存一些数据,这些数据可以使用第二个端点 / step2
。在这两个调用之间,
myvar
的值不应该为该用户更改。
我想知道有一种方法可以为每个用户实例化此过程,因为我需要如果一个用户更改该变量,它不会影响其他用户。我不一定需要使用全局变量,它只是公开我想要对端点执行的操作。
代码:
package main
import(
encoding / json
net / http
github.com/gorilla/mux
github.com/rs/cors
fmt
)
类型测试结构{
测试字符串`json:test,omitempty`
}
func main(){
var myvar =test
router:= mux.NewRouter()
router.HandleFunc(/ step1,func(w http.ResponseWriter,r * http.Request ){
var test Test b $ b _ = 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 {*},
AllowCreden tials:true,
AllowedMethods:[] string {GET,POST,PUT,DELETE,PATCH},
AllowedHeaders:[] string {*},
ExposedHeaders:[] string {*},
})
处理程序:= c.Handler(路由器)
http.ListenAndServe( :8003,handler)
}
请求由多个goroutines同时提供。这意味着如果他们读取/写入同一个变量,则必须对该变量进行同步。
接下来,如果您想为每个用户使用不同的此数据实例,那么您可以使用映射,从用户ID或名称映射到数据结构。假设数据结构是一个结构体,例如:
type customData struct {
Field1 string
Field2 int
//无论您需要什么字段
}
每个用户持有一张地图:
var userDataMap = map [string] customData {}
您可以使用 sync.RWMutex
用于保护一个地图,而它从一个goroutine读取/写入:
var mux =& sync.RWMutex {}
并且同步访问地图,使用上面的互斥体:
func Ge t(用户字符串)customData {
mux.RLock()
推迟mux.RUnlock()
返回userDataMap [用户]
}
func设置(用户字符串,数据customData){
mux.Lock()
userDataMap [user] = data
mux.Unlock()
}
另一个更复杂的解决方案是使用服务器端HTTP会话。有关详细信息,请参阅进入会话变量?
I'm new to Go and I have the following problem. I tried to simplify it:
I have a server which has for example a global variable myvar
. All users can POST the endpoint /step1
and save some data in the variable, which can be retrieved with a GET using the second endpoint /step2
. Between these 2 calls the value of myvar
shouldn't change for that user.
I would like to know if there is a way to instantiate this process for every user, because I need that if one user changes the variable, it doesn't affect the other users. I don't necessarily need to use the global variable, it is just to expose what I want to do with the endpoints.
Code:
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)
}
Requests are served from multiple goroutines, concurrently. This means if they read/write the same variable, access to this variable must be synchronized.
Next, if you want a different instance of this data for each user, you may use a map, mapping from user ID or name to the data structure.
Let's assume the data structure is a struct, e.g.:
type customData struct {
Field1 string
Field2 int
// Whatever fields you need
}
The map holding one for each user:
var userDataMap = map[string]customData{}
You may use a sync.RWMutex
for protecting a map while it is read / written from a goroutine:
var mux = &sync.RWMutex{}
And synchronized access to the map, using the above mutex:
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()
}
Another, more sophisticated solution would be to use server side HTTP sessions. For details, see Go session variables?
这篇关于有多个用户的服务器实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!