英文:
Online Game Login Design
问题
我目前正在开发一个在线游戏,但是在“登录服务器”方面遇到了设计问题。每个玩家只能从一个客户端登录,如果他尝试打开另一个客户端并尝试登录,应该提示该账户已经在另一个客户端登录。
这个功能已经实现了,但问题是当有人在完全相同的时间尝试从两个客户端登录时,两个客户端都能成功登录,导致账户在两个不同的地方登录。这不是我想要的结果。
我目前的方法是(我使用的是Go语言):
var onLogin map[string]uint16 = make(map[string]uint16)
func login(data []byte) []byte {
username := cstring(data[8:23])
password := cstring(data[24:39])
// 检查是否已经在尝试登录
_, loggingIn := onLogin[username]
if loggingIn {
fmt.Println("Possible double connect attempt", username)
return nil
}
(...检查登录信息是否正确...)
(...检查用户是否已经登录...)
// 在返回之前从列表中删除
delete(onLogin, username)
(...如果登录成功或失败,构建并发送回客户端的数据包...)
}
这个方法在一定程度上有所帮助,但是当有人能够在不可能的准确时间内同时按下两个客户端的“登录”按钮时,仍然会成功登录。也许我的设计有缺陷?有什么建议吗?谢谢!
英文:
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):
var onLogin map[string]uint16 = make(map[string]uint16)
func login(data []byte) []byte {
username := cstring(data[8:23])
password := cstring(data[24:39])
// check if already trying to login
_, loggingIn := onLogin[username]
if loggingIn {
fmt.Println("Possible double connect attempt", username)
return nil
}
(...check if correct login info...)
(...check if user is already logged in...)
// remove from list before returning
delete(onLogin, username)
(...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 是必读的。
// 编辑示例:
var onLogin = struct {
sync.Mutex
m map[string]bool
}{m: map[string]bool{}}
func login(data []byte) []byte {
username := cstring(data[8:23])
password := cstring(data[24:39])
onLogin.Lock()
defer onLogin.Unlock()
if _, loggingIn := onLogin.m[username]; loggingIn {
fmt.Println("Possible double connect attempt", username)
return nil
}
///....
}
英文:
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:
var onLogin = struct {
sync.Mutex
m map[string]bool
}{m: map[string]bool{}}
func login(data []byte) []byte {
username := cstring(data[8:23])
password := cstring(data[24:39])
onLogin.Lock()
defer onLogin.Unlock()
if _, loggingIn := onLogin.m[username]; loggingIn {
fmt.Println("Possible double connect attempt", username)
return nil
}
///....
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论