dongzhuo3202 2017-05-19 12:36
浏览 35
已采纳

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

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)
}
  • 写回答

1条回答 默认 最新

  • 普通网友 2017-05-19 12:39
    关注

    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?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效