Я пытался заставить SignalR запустить запрос к базе данных, а затем в зависимости от результата этого запроса ответить клиенту, который его инициировал.
Но я столкнулся с Невозможно получить доступ к удаленному объекту. из DatabaseContext и HubContext .Я испробовал несколько различных методов создания одного контроллера базы данных среди других, но ни один из них не сработал.
Мне наконец удалось создать решение, но теперь мне интересно, создаю ли я слишком много экземпляров / контекстов базы данныхконтекст.
Вот метод, который я придумал.(Упрощенно)
[Authorize(JwtBearerDefaults.AuthenticationScheme)]
public class Game : Hub
{
private GameContext _dbContext;
private IHubContext<Game> _hubContext;
public Game(IHubContext<Game> hubContext)
{
_hubContext = hubContext;
}
public override async Task OnConnectedAsync()
{
await Clients.Client(Context.ConnectionId).SendAsync("DebugMessage", "Connected to Hub");
await base.OnConnectedAsync();
}
public async void NewUser(string username, string userIdentifier)
{
_dbContext = new GameContext { };
string connectionID = Context.ConnectionId;
bool error = false;
bool usernameExists = false;
bool createdUser = false;
try
{
var rows = await _dbContext.Users.Where(x => x.Username == username).ToListAsync();
if (rows.Count > 0)
{
usernameExists = true;
goto SendResponse;
}
}
catch (Exception e)
{
error = true;
goto SendResponse;
}
Users user = new Users { Username = username, UserIdentifier = userIdentifier, Joined = DateTime.UtcNow };
try
{
_dbContext.Add(user);
await _dbContext.SaveChangesAsync();
createdUser = true;
goto SendResponse;
}
catch (Exception e)
{
error = true;
goto SendResponse;
}
SendResponse:
await _hubContext.Clients.Client(connectionID).SendAsync("CreatedUser", username, usernameExists, createdUser, error);
}
}
Как вы можете видеть в функции NewUser , я создаю новый экземпляр / контекст, чтобы он тоже работал.
Такое ощущение, что эторасточительно, поэтому сделайте шаблон Singleton для него в Game Hub, чтобы проверить, является ли он нулевым, и создайте новый, если необходимо, следующим образом.
private Object padlock = new Object { };
private GameContext _dbContextInstance;
private GameContext _dbContext
{
get
{
if (_dbContextInstance == null)
{
lock (padlock)
{
if (_dbContextInstance == null)
{
_dbContextInstance = new GameContext { };
}
}
}
return _dbContextInstance;
}
}
Но он все еще кажется расточительным, так как я постоянно делаю одно и то жеСнова и снова, когда пользователь делает много звонков, он складывается, поэтому, прежде чем я продолжу, я хотел бы знать, иду ли я по неверному маршруту с этим и если да, то по какому маршруту я должен идти.
Спасибо