Fix an issue that pushing may miss messages.

This commit is contained in:
xuef
2023-11-28 07:18:18 +00:00
parent 4ee0a1aaf4
commit 6a2ca8a69b
@@ -53,33 +53,41 @@ public class GamesController : Controller
} }
}); });
} }
[Route("games/{id}/ws")] [Route("games/{id}/ws")]
public async Task GetWebSocket([FromRoute] int id) public async Task GetWebSocket([FromRoute] int id)
{ {
var lastReadId = _counter.GetCurrent; var lastReadId = _counter.GetCurrent;
var (channel, blocker) = _database.ListenChannel(id); var (channel, blocker) = _database.ListenChannel(id);
await _pusher.Accept(HttpContext); await _pusher.Accept(HttpContext);
try try
{ {
await Task.Factory.StartNew(_pusher.PendingClose); await Task.Factory.StartNew(_pusher.PendingClose);
while (_pusher.Connected) while (_pusher.Connected)
{ {
while (true)
{
var nextMessages = channel
.GetMessagesFrom(lastReadId);
if (!nextMessages.Any())
{
break;
}
var messageToPush = nextMessages.MinBy(t => t.Id);
await _pusher.SendMessage(messageToPush!.Content);
lastReadId = messageToPush.Id;
}
await blocker.WaitAsync(); await blocker.WaitAsync();
var nextMessages = channel
.GetMessagesFrom(lastReadId)
.ToList();
var messageToPush = nextMessages.MinBy(t => t.Id);
await _pusher.SendMessage(messageToPush!.Content);
lastReadId = messageToPush.Id;
} }
} }
finally finally
{ {
await _pusher.Close(); await _pusher.Close();
if (!channel.UnRegister(out blocker)) if (!channel.UnRegister(out blocker))
{ {
throw new InvalidOperationException("Failed to unregister blocker!"); throw new InvalidOperationException("Failed to unregister blocker!");
} }
} }
@@ -93,7 +101,7 @@ public class GamesController : Controller
var game = _database.GetOrAdd(id); var game = _database.GetOrAdd(id);
return Ok(game.ToAscii()); return Ok(game.ToAscii());
} }
[Route("games/{id}/html")] [Route("games/{id}/html")]
public IActionResult GetHtml([FromRoute] int id) public IActionResult GetHtml([FromRoute] int id)
{ {
@@ -108,7 +116,7 @@ public class GamesController : Controller
} }
[Route("games/{id}/pgn")] [Route("games/{id}/pgn")]
public IActionResult GetPgn([FromRoute]int id) public IActionResult GetPgn([FromRoute] int id)
{ {
var game = _database.GetOrAdd(id); var game = _database.GetOrAdd(id);
return Ok(game.ToPgn()); return Ok(game.ToPgn());
@@ -116,7 +124,7 @@ public class GamesController : Controller
[HttpPost] [HttpPost]
[Route("games/{id}/move/{player}/{move}")] [Route("games/{id}/move/{player}/{move}")]
public IActionResult Move([FromRoute]int id, [FromRoute]string player, [FromRoute]string move) public IActionResult Move([FromRoute] int id, [FromRoute] string player, [FromRoute] string move)
{ {
var game = _database.GetOrAdd(id); var game = _database.GetOrAdd(id);
try try