-
Notifications
You must be signed in to change notification settings - Fork 56
Conference Management (for devs)
Conference Management is the heart of Strive: The entire logic of the features of a conference are managed here. It is responsible for synchronizing participants, handling permissions and managing connections.
In Strive we use the Mediator pattern to execute commands and publish events. MediatR is the library used to define the mediator.
Autofac is used as dependency injection container. Every project contains a Module class in the main directory which registers the services provided by this class.
Logging is handled by Microsoft.Extensions.Logging.Abstractions, which is currently implemented by Serilog.
As it should be possible to use Strive with load balancing, do not keep any state in instances. Use the key value repositories for temporary state and the database to persist objects. Some applies for timers, locks, etc.
The conference management is split into three main projects:
- Strive (presentation layer)
- Strive.Core (business layer)
- Strive.Infrastructure (infrastructure layer)
As Strive is using the Onion Architecture, Strive.Core doesn't have any dependencies on the "outside" and should be as library agnostic as possible. This includes database implementations.
Directories:
-
/Domainincludes entities that are important to many different services. The most important class isConference, which is used by most services and includes very basic information about a conference (which is also persisted in a database) -
/Dtoincludes dtos that are important to many different services.Erroris the most important class here at the moment and is used as a base class to report errors to the user interface -
/Errorsimplements different error types. The types are similar to the HTTP status codes (so we can map them easily when responding the error). The name of the errors should be descriptive. -
/Extensionssome common extensions -
/Interfacesbasicaly dependencies to the outside that must be implemented somehow (as they are injected using DI) -
/Servicesthis folder contains the specific features Strive offers. More information provided below -
/Specificationsused to query the database using Linq -
/Utilitiessome utilities used by multiple services -
CoreModulethe Autofac module to register the classes of this project
All features of Strive (chat, polls, rooms, etc.) are structured in services which can also have dependencies (but that should all be handled by the Mediator pattern).
Typically, a service contains these folders:
-
/Gatewaysrepositories to store data (usually implementingIStateRepository). These repositories are implemented by the infrastructure layer. -
/NotificationHandlersmediator handlers for notifications including common ones likeConferenceOpenedNotification,ParticipantJoinedNotificationetc. -
/Notificationsmediator notifications provided by this service -
/Requestsmediator requests for this service (actions) -
/UseCasesmediator handlers for requests from the/Requestsfolder
Additionally, there are some standard files:
-
<ServiceName>Errordefines errors thrown by this service -
Synchronized<ServiceName>andSynchronized<ServiceName>Providerare for state synchronization (more info below)
A special service is Synchronization which provides an easy to use interface to synchronize objects to a specific group of participants. First of all, you have to define a simple DTO class (a POCO), that just keeps the information you want to synchronize (records are an amazing choice here).
Then, you have to define a ISynchronizedObjectProvider that has the following interface:
Type Type { get; }
string Id { get; }
ValueTask<object> FetchValue(string conferenceId, SynchronizedObjectId synchronizedObjectId);
ValueTask<IEnumerable<SynchronizedObjectId>> GetAvailableObjects(Participant participant);The Type must be assigned to the DTO class you just created. The Id must be a unique identifier for the object type (which is read by the frontend). GetAvailableObjects returns the object ids a participant may access. There may be multiple instances of an object within a conference (for example every participant has its own permissions), so in turn to have unique object ids, you can include the participant id in the returned object id (of the specific participant). Also, it is possible to check for admin rights here and return permissions objects of all participants if the requesting user is an admin. Of course there may also be only one instance that can be accessed by everyone, so you can just return the Id.
FetchValue fetches the value of an object. Caching etc. is managed by the framework. Please make sure that the value can always be fetched.
For simplication, there exists the SynchronizedObjectProvider<T> class which automatically fills the Type and SynchronizedObjectProviderForAll<T> which returns the same object id for every participant (when you only have a single instance for everyone).
SynchronizedObjectProvider<T> is automatically registered in the DI Container, but you cannot keep any state as a new instance may be created or the same provider may be reused for different conferences. Use repositories for that.
This layer connects the business layer to actual implementations of services (databases, etc.).
Directories:
-
Authservices for authentication -
Dataclasses for persistence, currently implemented by MongoDB -
Extensionssome extensions used in the infrastructure layer -
KeyValueimplementation of state repositories, currently implemented by Redis (actually, there is another abstraction for integration tests) -
Schedulerused for scheduling notifications (for timers etc.) -
Serializationimportant classes for Json and Bson serialization for some objects -
Sfusome classes to handle the connection to the SFU -
Utilitiessome utilities used in the infrastructure and presentation layer
Directories:
-
Authprovides utilities for authentication -
Configconfiguration classes for serveral services -
ControllersHttp Api -
Extensionsextensions for the presentation layer -
HubsSignalR Hubs used for real time communication -
Messaginghandlers for RabbitMQ MassTransit -
ModelsDTOs for http requests and responses including validators -
Presentersused to map data from databases to dtos for users -
Servicesbasic services for the presentation layer -
Utilitiesbasic utilities for the presentation layer