Merge branch 'main' into feature-join-whiteboard-by-code
# Conflicts: # dotnet/AipsRT/Hubs/WhiteboardHub.cs # dotnet/AipsRT/Services/Interfaces/IMessagingService.cs # front/src/stores/whiteboard.ts
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
namespace AipsCore.Application.Abstract;
|
||||||
|
|
||||||
|
public interface IWhiteboardAwareContext
|
||||||
|
{
|
||||||
|
Guid GetWhiteboardId();
|
||||||
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
|
using AipsCore.Application.Abstract;
|
||||||
using AipsCore.Application.Abstract.MessageBroking;
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
using AipsCore.Application.Models.Shape.Command.CreateArrow;
|
using AipsCore.Application.Models.Shape.Command.CreateArrow;
|
||||||
|
|
||||||
namespace AipsCore.Application.Common.Message.AddArrow;
|
namespace AipsCore.Application.Common.Message.AddArrow;
|
||||||
|
|
||||||
public record AddArrowMessage(CreateArrowCommand Command) : IMessage;
|
public record AddArrowMessage(CreateArrowCommand Command) : IMessage, IWhiteboardAwareContext
|
||||||
|
{
|
||||||
|
public Guid GetWhiteboardId()
|
||||||
|
{
|
||||||
|
return Guid.Parse(Command.WhiteboardId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
|
using AipsCore.Application.Abstract;
|
||||||
using AipsCore.Application.Abstract.MessageBroking;
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
using AipsCore.Application.Models.Shape.Command.CreateLine;
|
using AipsCore.Application.Models.Shape.Command.CreateLine;
|
||||||
|
|
||||||
namespace AipsCore.Application.Common.Message.AddLine;
|
namespace AipsCore.Application.Common.Message.AddLine;
|
||||||
|
|
||||||
public record AddLineMessage(CreateLineCommand Command) : IMessage;
|
public record AddLineMessage(CreateLineCommand Command) : IMessage, IWhiteboardAwareContext
|
||||||
|
{
|
||||||
|
public Guid GetWhiteboardId()
|
||||||
|
{
|
||||||
|
return Guid.Parse(Command.WhiteboardId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
|
using AipsCore.Application.Abstract;
|
||||||
using AipsCore.Application.Abstract.MessageBroking;
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
using AipsCore.Application.Models.Shape.Command.CreateRectangle;
|
using AipsCore.Application.Models.Shape.Command.CreateRectangle;
|
||||||
|
|
||||||
namespace AipsCore.Application.Common.Message.AddRectangle;
|
namespace AipsCore.Application.Common.Message.AddRectangle;
|
||||||
|
|
||||||
public record AddRectangleMessage(CreateRectangleCommand Command) : IMessage;
|
public record AddRectangleMessage(CreateRectangleCommand Command) : IMessage, IWhiteboardAwareContext
|
||||||
|
{
|
||||||
|
public Guid GetWhiteboardId()
|
||||||
|
{
|
||||||
|
return Guid.Parse(Command.WhiteboardId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
|
using AipsCore.Application.Abstract;
|
||||||
using AipsCore.Application.Abstract.MessageBroking;
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
using AipsCore.Application.Models.Shape.Command.CreateTextShape;
|
using AipsCore.Application.Models.Shape.Command.CreateTextShape;
|
||||||
|
|
||||||
namespace AipsCore.Application.Common.Message.AddTextShape;
|
namespace AipsCore.Application.Common.Message.AddTextShape;
|
||||||
|
|
||||||
public record AddTextShapeMessage(CreateTextShapeCommand Command) : IMessage;
|
public record AddTextShapeMessage(CreateTextShapeCommand Command) : IMessage, IWhiteboardAwareContext
|
||||||
|
{
|
||||||
|
public Guid GetWhiteboardId()
|
||||||
|
{
|
||||||
|
return Guid.Parse(Command.WhiteboardId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using AipsCore.Application.Abstract;
|
||||||
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
|
using AipsCore.Domain.Common.Validation;
|
||||||
|
|
||||||
|
namespace AipsCore.Application.Common.Message.ErrorMessage;
|
||||||
|
|
||||||
|
public record ErrorMessage(Guid WhiteboardId, ICollection<ValidationError> Errors) : IMessage, IWhiteboardAwareContext
|
||||||
|
{
|
||||||
|
public Guid GetWhiteboardId()
|
||||||
|
{
|
||||||
|
return WhiteboardId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
|
|
||||||
|
namespace AipsCore.Application.Common.Message.ErrorMessage;
|
||||||
|
|
||||||
|
public class ErrorMessageHandler : IMessageHandler<ErrorMessage>
|
||||||
|
{
|
||||||
|
private readonly IErrorMessageHandleStrategy _handleStrategy;
|
||||||
|
|
||||||
|
public ErrorMessageHandler(IErrorMessageHandleStrategy handleStrategy)
|
||||||
|
{
|
||||||
|
_handleStrategy = handleStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Handle(ErrorMessage message, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await _handleStrategy.Handle(message, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace AipsCore.Application.Common.Message.ErrorMessage;
|
||||||
|
|
||||||
|
public interface IErrorMessageHandleStrategy
|
||||||
|
{
|
||||||
|
Task Handle(ErrorMessage message, CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
|
using AipsCore.Application.Abstract;
|
||||||
using AipsCore.Application.Abstract.MessageBroking;
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
using AipsCore.Application.Models.Shape.Command.MoveShape;
|
using AipsCore.Application.Models.Shape.Command.MoveShape;
|
||||||
|
|
||||||
namespace AipsCore.Application.Common.Message.MoveShape;
|
namespace AipsCore.Application.Common.Message.MoveShape;
|
||||||
|
|
||||||
public record MoveShapeMessage(MoveShapeCommand Command) : IMessage;
|
public record MoveShapeMessage(Guid WhiteboardId, MoveShapeCommand Command) : IMessage, IWhiteboardAwareContext
|
||||||
|
{
|
||||||
|
public Guid GetWhiteboardId()
|
||||||
|
{
|
||||||
|
return WhiteboardId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ public class WhiteboardHub : Hub
|
|||||||
{
|
{
|
||||||
if (!_whiteboardManager.WhiteboardExists(whiteboardId))
|
if (!_whiteboardManager.WhiteboardExists(whiteboardId))
|
||||||
{
|
{
|
||||||
await _whiteboardManager.AddWhiteboard(whiteboardId);
|
await _whiteboardManager.LoadWhiteboard(whiteboardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Groups.AddToGroupAsync(Context.ConnectionId, whiteboardId.ToString());
|
await Groups.AddToGroupAsync(Context.ConnectionId, whiteboardId.ToString());
|
||||||
@@ -210,6 +210,6 @@ public class WhiteboardHub : Hub
|
|||||||
|
|
||||||
await MoveShape(moveShape);
|
await MoveShape(moveShape);
|
||||||
|
|
||||||
await _messagingService.MoveShape(moveShape);
|
await _messagingService.MoveShape(CurrentWhiteboard.WhiteboardId, moveShape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ public class WhiteboardManager
|
|||||||
_scopeFactory = scopeFactory;
|
_scopeFactory = scopeFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddWhiteboard(Guid whiteboardId)
|
public async Task LoadWhiteboard(Guid whiteboardId)
|
||||||
{
|
{
|
||||||
var getWhiteboardService = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<GetWhiteboardService>();
|
var getWhiteboardService = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<GetWhiteboardService>();
|
||||||
var whiteboard = await getWhiteboardService.GetWhiteboard(whiteboardId);
|
var whiteboard = await getWhiteboardService.GetWhiteboard(whiteboardId);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using AipsCore.Application.Common.Message.ErrorMessage;
|
||||||
using AipsCore.Infrastructure.DI;
|
using AipsCore.Infrastructure.DI;
|
||||||
using AipsRT.Hubs;
|
using AipsRT.Hubs;
|
||||||
using AipsRT.Model.Whiteboard;
|
using AipsRT.Model.Whiteboard;
|
||||||
@@ -15,6 +16,10 @@ builder.Configuration.AddEnvironmentVariables();
|
|||||||
builder.Services.AddSignalR();
|
builder.Services.AddSignalR();
|
||||||
|
|
||||||
builder.Services.AddAips(builder.Configuration);
|
builder.Services.AddAips(builder.Configuration);
|
||||||
|
builder.Services.AddAipsMessageHandlers();
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<IErrorMessageHandleStrategy, RtErrorHandleStrategy>();
|
||||||
|
builder.Services.AddHostedService<ErrorSubscriberBackgroundService>();
|
||||||
|
|
||||||
builder.Services.AddScoped<GetWhiteboardService>();
|
builder.Services.AddScoped<GetWhiteboardService>();
|
||||||
builder.Services.AddSingleton<WhiteboardManager>();
|
builder.Services.AddSingleton<WhiteboardManager>();
|
||||||
|
|||||||
25
dotnet/AipsRT/Services/ErrorSubscriberBackgroundService.cs
Normal file
25
dotnet/AipsRT/Services/ErrorSubscriberBackgroundService.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using AipsCore.Application.Abstract;
|
||||||
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
|
using AipsCore.Application.Common.Message.ErrorMessage;
|
||||||
|
|
||||||
|
namespace AipsRT.Services;
|
||||||
|
|
||||||
|
public class ErrorSubscriberBackgroundService : BackgroundService
|
||||||
|
{
|
||||||
|
private readonly IMessageSubscriber _subscriber;
|
||||||
|
private readonly IDispatcher _dispatcher;
|
||||||
|
|
||||||
|
public ErrorSubscriberBackgroundService(IMessageSubscriber subscriber, IDispatcher dispatcher)
|
||||||
|
{
|
||||||
|
_subscriber = subscriber;
|
||||||
|
_dispatcher = dispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
await _subscriber.SubscribeAsync<ErrorMessage>(async (errorMessage, ct) =>
|
||||||
|
{
|
||||||
|
await _dispatcher.Execute(errorMessage, ct);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,8 +12,8 @@ public interface IMessagingService
|
|||||||
Task CreatedArrow(Guid whiteboardId, Arrow arrow);
|
Task CreatedArrow(Guid whiteboardId, Arrow arrow);
|
||||||
Task CreateLine(Guid whiteboardId, Line line);
|
Task CreateLine(Guid whiteboardId, Line line);
|
||||||
Task CreateTextShape(Guid whiteboardId, TextShape textShape);
|
Task CreateTextShape(Guid whiteboardId, TextShape textShape);
|
||||||
|
|
||||||
Task MoveShape(MoveShapeCommand moveShape);
|
Task MoveShape(Guid whiteboardId, MoveShapeCommand moveShape);
|
||||||
|
|
||||||
Task AcceptedUser(AcceptUserRequestToJoinCommand command);
|
Task AcceptedUser(AcceptUserRequestToJoinCommand command);
|
||||||
Task RejectedUser(RejectUserRequestToJoinCommand command);
|
Task RejectedUser(RejectUserRequestToJoinCommand command);
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ public class MessagingService : IMessagingService
|
|||||||
await _messagePublisher.PublishAsync(message);
|
await _messagePublisher.PublishAsync(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task MoveShape(MoveShapeCommand moveShape)
|
public async Task MoveShape(Guid whiteboardId, MoveShapeCommand moveShape)
|
||||||
{
|
{
|
||||||
var message = new MoveShapeMessage(moveShape);
|
var message = new MoveShapeMessage(whiteboardId, moveShape);
|
||||||
await _messagePublisher.PublishAsync(message);
|
await _messagePublisher.PublishAsync(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
dotnet/AipsRT/Services/RtErrorHandleStrategy.cs
Normal file
29
dotnet/AipsRT/Services/RtErrorHandleStrategy.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using AipsCore.Application.Common.Message.ErrorMessage;
|
||||||
|
using AipsRT.Hubs;
|
||||||
|
using AipsRT.Model.Whiteboard;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
|
||||||
|
namespace AipsRT.Services;
|
||||||
|
|
||||||
|
public class RtErrorHandleStrategy : IErrorMessageHandleStrategy
|
||||||
|
{
|
||||||
|
private readonly IHubContext<WhiteboardHub> _hubContext;
|
||||||
|
private readonly WhiteboardManager _whiteboardManager;
|
||||||
|
|
||||||
|
public RtErrorHandleStrategy(IHubContext<WhiteboardHub> hubContext, WhiteboardManager whiteboardManager)
|
||||||
|
{
|
||||||
|
_hubContext = hubContext;
|
||||||
|
_whiteboardManager = whiteboardManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Handle(ErrorMessage message, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await _whiteboardManager.LoadWhiteboard(message.WhiteboardId);
|
||||||
|
|
||||||
|
var whiteboard = _whiteboardManager.GetWhiteboard(message.WhiteboardId)!;
|
||||||
|
|
||||||
|
await _hubContext.Clients
|
||||||
|
.Group(whiteboard.WhiteboardId.ToString())
|
||||||
|
.SendAsync("InitWhiteboard", whiteboard, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using AipsCore.Application.Abstract;
|
using AipsCore.Application.Abstract;
|
||||||
using AipsCore.Application.Abstract.MessageBroking;
|
using AipsCore.Application.Abstract.MessageBroking;
|
||||||
|
using AipsCore.Application.Common.Message.ErrorMessage;
|
||||||
using AipsCore.Application.Common.Message.TestMessage;
|
using AipsCore.Application.Common.Message.TestMessage;
|
||||||
using AipsCore.Domain.Common.Validation;
|
using AipsCore.Domain.Common.Validation;
|
||||||
using AipsWorker.Utilities;
|
using AipsWorker.Utilities;
|
||||||
@@ -12,12 +13,14 @@ public class WorkerService : BackgroundService
|
|||||||
{
|
{
|
||||||
private readonly IDispatcher _dispatcher;
|
private readonly IDispatcher _dispatcher;
|
||||||
private readonly IMessageTypesProvider _messageTypesProvider;
|
private readonly IMessageTypesProvider _messageTypesProvider;
|
||||||
|
private readonly IMessagePublisher _publisher;
|
||||||
private readonly SubscribeMethodUtility _subscribeMethodUtility;
|
private readonly SubscribeMethodUtility _subscribeMethodUtility;
|
||||||
|
|
||||||
public WorkerService(IMessageSubscriber subscriber, IDispatcher dispatcher, IMessageTypesProvider messageTypesProvider)
|
public WorkerService(IMessageSubscriber subscriber, IDispatcher dispatcher, IMessageTypesProvider messageTypesProvider, IMessagePublisher publisher)
|
||||||
{
|
{
|
||||||
_dispatcher = dispatcher;
|
_dispatcher = dispatcher;
|
||||||
_messageTypesProvider = messageTypesProvider;
|
_messageTypesProvider = messageTypesProvider;
|
||||||
|
_publisher = publisher;
|
||||||
_subscribeMethodUtility = new SubscribeMethodUtility(subscriber);
|
_subscribeMethodUtility = new SubscribeMethodUtility(subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,15 +40,26 @@ public class WorkerService : BackgroundService
|
|||||||
|
|
||||||
private async Task HandleMessage<T>(T message, CancellationToken ct) where T : IMessage
|
private async Task HandleMessage<T>(T message, CancellationToken ct) where T : IMessage
|
||||||
{
|
{
|
||||||
|
Console.WriteLine($"*--------{message.GetType().Name}--------*");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _dispatcher.Execute(message, ct);
|
await _dispatcher.Execute(message, ct);
|
||||||
|
|
||||||
Console.WriteLine($"OK: {message.GetType().Name}");
|
Console.WriteLine("OK!");
|
||||||
}
|
}
|
||||||
catch (ValidationException validationException)
|
catch (ValidationException validationException)
|
||||||
{
|
{
|
||||||
Console.WriteLine("===Validation Exception: ");
|
if (message is IWhiteboardAwareContext)
|
||||||
|
{
|
||||||
|
var whiteboardId = ((IWhiteboardAwareContext)message).GetWhiteboardId();
|
||||||
|
|
||||||
|
var errorMessage = new ErrorMessage(whiteboardId, validationException.ValidationErrors);
|
||||||
|
|
||||||
|
await _publisher.PublishAsync(errorMessage, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Validation Exception: ");
|
||||||
foreach (var error in validationException.ValidationErrors)
|
foreach (var error in validationException.ValidationErrors)
|
||||||
{
|
{
|
||||||
Console.WriteLine(" * Code: " + error.Code);
|
Console.WriteLine(" * Code: " + error.Code);
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export const useWhiteboardStore = defineStore('whiteboard', () => {
|
|||||||
|
|
||||||
function registerHubEvents() {
|
function registerHubEvents() {
|
||||||
whiteboardHubService.onInitWhiteboard((wb) => {
|
whiteboardHubService.onInitWhiteboard((wb) => {
|
||||||
|
deselectShape()
|
||||||
whiteboard.value = wb
|
whiteboard.value = wb
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user