Synchronise les parties entre les deux devices

This commit is contained in:
2026-04-15 23:40:18 +02:00
parent 3b88b9abe6
commit e0c3a41ccd
11 changed files with 527 additions and 18 deletions

View File

@@ -0,0 +1,89 @@
namespace ChessCubing.Server.Social;
public sealed class CollaborativeMatchCoordinator
{
private readonly object _sync = new();
private readonly Dictionary<string, CollaborativeSessionState> _sessions = new(StringComparer.Ordinal);
public void RegisterSession(PlaySessionResponse session)
{
lock (_sync)
{
_sessions[session.SessionId] = new CollaborativeSessionState(
session.SessionId,
new HashSet<string>(StringComparer.Ordinal)
{
session.WhiteSubject,
session.BlackSubject,
session.InitiatorSubject,
session.RecipientSubject,
},
null,
0);
}
}
public bool CanAccessSession(string sessionId, string subject)
{
lock (_sync)
{
return _sessions.TryGetValue(sessionId, out var session)
&& session.ParticipantSubjects.Contains(subject);
}
}
public CollaborativeMatchStateMessage? GetLatestState(string sessionId, string subject)
{
lock (_sync)
{
if (!_sessions.TryGetValue(sessionId, out var session) ||
!session.ParticipantSubjects.Contains(subject))
{
throw new SocialValidationException("Cette session de partie est introuvable ou n'est pas accessible.");
}
return session.LatestState;
}
}
public CollaborativeMatchStateMessage PublishState(
string sessionId,
string subject,
string? matchJson,
string route)
{
lock (_sync)
{
if (!_sessions.TryGetValue(sessionId, out var session) ||
!session.ParticipantSubjects.Contains(subject))
{
throw new SocialValidationException("Cette session de partie est introuvable ou n'est pas accessible.");
}
var revision = session.Revision + 1;
var message = new CollaborativeMatchStateMessage
{
SessionId = sessionId,
MatchJson = matchJson,
Route = string.IsNullOrWhiteSpace(route) ? "/application.html" : route.Trim(),
SenderSubject = subject,
Revision = revision,
UpdatedUtc = DateTime.UtcNow,
};
_sessions[sessionId] = session with
{
Revision = revision,
LatestState = message,
};
return message;
}
}
private sealed record CollaborativeSessionState(
string SessionId,
HashSet<string> ParticipantSubjects,
CollaborativeMatchStateMessage? LatestState,
long Revision);
}