在线游戏登录设计

huangapple go评论123阅读模式
英文:

Online Game Login Design

问题

我目前正在开发一个在线游戏,但是在“登录服务器”方面遇到了设计问题。每个玩家只能从一个客户端登录,如果他尝试打开另一个客户端并尝试登录,应该提示该账户已经在另一个客户端登录。

这个功能已经实现了,但问题是当有人在完全相同的时间尝试从两个客户端登录时,两个客户端都能成功登录,导致账户在两个不同的地方登录。这不是我想要的结果。

我目前的方法是(我使用的是Go语言):

  1. var onLogin map[string]uint16 = make(map[string]uint16)
  2. func login(data []byte) []byte {
  3. username := cstring(data[8:23])
  4. password := cstring(data[24:39])
  5. // 检查是否已经在尝试登录
  6. _, loggingIn := onLogin[username]
  7. if loggingIn {
  8. fmt.Println("Possible double connect attempt", username)
  9. return nil
  10. }
  11. (...检查登录信息是否正确...)
  12. (...检查用户是否已经登录...)
  13. // 在返回之前从列表中删除
  14. delete(onLogin, username)
  15. (...如果登录成功或失败构建并发送回客户端的数据包...)
  16. }

这个方法在一定程度上有所帮助,但是当有人能够在不可能的准确时间内同时按下两个客户端的“登录”按钮时,仍然会成功登录。也许我的设计有缺陷?有什么建议吗?谢谢!

英文:

I am currently working on an online game and I have a design problem with the login server. Each player must only be logged-in from one client, if he tries to open another client and tries to login it should tell that the account is already logged in from another client.

That works, but the problem is when someone tries to login from 2 clients at the exact same time both clients go through, causing the account to be logged-in in 2 different places. Which is something I do not wan't.

My current approach is like (I'm using GoLang):

  1. var onLogin map[string]uint16 = make(map[string]uint16)
  2. func login(data []byte) []byte {
  3. username := cstring(data[8:23])
  4. password := cstring(data[24:39])
  5. // check if already trying to login
  6. _, loggingIn := onLogin[username]
  7. if loggingIn {
  8. fmt.Println("Possible double connect attempt", username)
  9. return nil
  10. }
  11. (...check if correct login info...)
  12. (...check if user is already logged in...)
  13. // remove from list before returning
  14. delete(onLogin, username)
  15. (...build and send back packet to client if login success or fail...)

It helps (A BIT) but when someone is able to press the LOGIN button on 2 clients at inhumanly exact same time it still goes through. Maybe my design is flawed? Any advice? Cheers!

答案1

得分: 3

你的onLogin函数需要一个互斥锁(mutex),如果你使用-race参数运行代码,它会告诉你存在竞争条件。

Race Detector 是必读的。

// 编辑示例:

  1. var onLogin = struct {
  2. sync.Mutex
  3. m map[string]bool
  4. }{m: map[string]bool{}}
  5. func login(data []byte) []byte {
  6. username := cstring(data[8:23])
  7. password := cstring(data[24:39])
  8. onLogin.Lock()
  9. defer onLogin.Unlock()
  10. if _, loggingIn := onLogin.m[username]; loggingIn {
  11. fmt.Println("Possible double connect attempt", username)
  12. return nil
  13. }
  14. ///....
  15. }
英文:

Your onLogin needs a mutex, if you run your code with -race it will tell you there's a race.

Race Detector is a must read.

// edit example:

  1. var onLogin = struct {
  2. sync.Mutex
  3. m map[string]bool
  4. }{m: map[string]bool{}}
  5. func login(data []byte) []byte {
  6. username := cstring(data[8:23])
  7. password := cstring(data[24:39])
  8. onLogin.Lock()
  9. defer onLogin.Unlock()
  10. if _, loggingIn := onLogin.m[username]; loggingIn {
  11. fmt.Println("Possible double connect attempt", username)
  12. return nil
  13. }
  14. ///....
  15. }

huangapple
  • 本文由 发表于 2016年2月6日 05:13:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/35233626.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定