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

标签 go concurrency server

我是 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/

相关文章:

node.js - 有人可以解释一下 GO lang 的架构吗,它比 Nodejs 更快吗?如果是的话,是什么让它更快

session - 在 golang 中检查 HTML 文件中的用户 session

java - CopyOnWriteArrayList 如何是线程安全的?

php - 如何允许自定义构建的 "Scan this dir for additional .ini files"php.ini 文件读取

python - python创建DDE服务器并持续发送数据

c - 我如何修改这个迭代服务器以获得最高的文件描述符?

go - Golang 中奇怪的类型定义语法(名称,然后是类型,然后是字符串文字)

windows - 为什么 "go get gopkg.in/..."不工作而 "go get github.com/..."正常?

ios - Alamofire 请求未在 NSOperation 中运行完成 block

java - 交替运行两个线程的最佳方式?