我正在使用dotnet core 2.2控制台应用程序创建游戏服务器,我对实体框架在某些环境下的工作方式有一些误解。我想将用户信息存储在内存中,但要牢记两个重要因素。
这是我目前的操作方式:
DatabaseManager.cs
internal static class DatabaseManager
{
public static async Task<User> FindUser(int userId, string token)
{
using (var dbContext = new musicContext())
{
return await dbContext.User.FirstOrDefaultAsync(u =>
u.UserId == userId && string.Equals(u.Token, token, StringComparison.InvariantCulture));
}
}
public static IEnumerable<Game> GetUserGames(User user)
{
using (var dbContext = new musicContext())
{
return dbContext.Game
.Include(g => g.ParticipantOneNavigation)
.Include(g => g.ParticipantTwoNavigation)
.Where(g =>
g.ParticipantOneNavigation == user || g.ParticipantTwoNavigation == user);
}
}
}
Player.cs
internal class Player : IEquatable<Player>
{
private readonly NetPeer _netPeer;
private User _user;
private int _userId;
private string _token;
public Player(NetPeer netPeer)
{
_netPeer = netPeer;
}
public async Task<bool> Authenticate(int userId, string token)
{
_user = await DatabaseManager.FindUser(userId, token);
if (_user is null)
return false;
_userId = userId;
_token = token;
return true;
}
public NetPeer GetPeer()
{
return _netPeer;
}
public int GetPlayerId()
{
FlushData();
return _user.UserId;
}
public string GetUsername()
{
FlushData();
return _user.Username;
}
public string GetNickname()
{
FlushData();
return _user.Nickname;
}
public string GetPhoneNumber()
{
FlushData();
return _user.PhoneNumber;
}
public int GetCoins()
{
FlushData();
return _user.Coins;
}
public int GetCups()
{
FlushData();
return _user.Cups;
}
public bool IsAuthenticated()
{
return _user != null;
}
public bool IsSuspended(out DateTimeOffset suspendedUntil)
{
suspendedUntil = _user.SuspendedUntil.GetValueOrDefault();
return _user.Suspended;
}
public bool Equals(Player other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return _playerId == other._playerId;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals((Player)obj);
}
public override int GetHashCode()
{
return _playerId;
}
private async void FlushData()
{
_user = await DatabaseManager.FindUser(_userId, _token);
}
}
这是一种最佳的做法吗?如果没有,您建议如何改善它?
答案 0 :(得分:0)
您不能这样做,因为数据库是用于数据持久性的,并且不可避免地要进行频繁的查询才能使数据始终保持最新。
如果您需要实时信息交换工具,则需要开发和运行具有双工通信的服务器端应用程序(例如UDP,TCP,WebSocket。对于.NET Core,ASP.NET Core SignalR是建议)。它可以缓存,通知数据更新并将其推送到客户端。为了保留数据,您可以通过服务器端应用程序定期从缓存中更新数据库。这也可能有益于业务数据的完整性和安全性。