单点登录高性能WebSocket游戏服务器

本文关键字:游戏 服务器 WebSocket 高性能 登录 单点 | 更新日期: 2023-09-27 18:04:29

我正在开发一个使用WebSocket协议的c#游戏服务器(通过WebSocketSharp)。目前,每当用户登录游戏时,我都会创建一个令牌并将其添加到ConcurrentDictionary中。现在我需要一个用户一次只能登录一次,并且在将来,服务器程序可能在相同或不同的物理机器上运行多个实例,我需要从内存迁移到数据库。

然而,我需要一个非常高性能的认证验证每个WebSocket请求(我有一个类似会话的保存令牌)。因此,我打算将令牌从数据库缓存到内存(旧的ConcurrentDictionary),因为为每个请求检查数据库不是一个选项。

但是现在我遇到了同步的另一个问题。我有两个想法:

  • 一旦该帐户的令牌已经存在,阻止第二个设备登录。当用户注销时,令牌将被销毁。然而,它是不可靠的,因为用户可能无法正确登出(例如网络问题)。在这种情况下,用户帐户可能会在会话/令牌生命周期中卡住。如果令牌生命周期太短而无法防止问题,那么我的服务器必须过于频繁地检查数据库。
  • 给予用户再次登录的能力,如果已经有令牌,用户可以选择另一个登录,所以第一个用户可能会在游戏中被踢,而新的用户会取而代之(这种行为类似于Steam游戏)。但是,如果不经常检查数据库,服务器如何知道第一个令牌在到期时间之前被踢出?

请分享一些关于这个问题的经验和/或正确的解决方法。

单点登录高性能WebSocket游戏服务器

如何设置集群,以便用户始终被定向到同一台服务器(如果已启动),直到会话超时?所有负载均衡器都支持会话保持。

使用粘性会导致给定用户总是访问同一台服务器。因此,您可以使用专用的内存机制来验证身份验证令牌。如果服务器崩溃,LB通常会知道服务器已关闭,并将数据包定向到另一台服务器。该服务器应该能够检测到身份验证票据无效(在该服务器上),并指示用户重新进行身份验证。据推测,这是可以的,因为当服务器崩溃时,正在进行的游戏状态将会丢失。