Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
H
HIAST-Clinics
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
almohanad.hafez
HIAST-Clinics
Commits
0d73b915
Unverified
Commit
0d73b915
authored
Aug 22, 2024
by
Almouhannad Hafez
Committed by
GitHub
Aug 22, 2024
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #13 from Almouhannad/B_Add-SignalR
B add signal r
parents
33ad80b5
0f2dd34b
Changes
14
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
394 additions
and
8 deletions
+394
-8
API.csproj
Clinics.Backend/API/API.csproj
+1
-0
Program.cs
Clinics.Backend/API/Program.cs
+25
-2
Clinics.Backend.sln
Clinics.Backend/Clinics.Backend.sln
+8
-1
ServerTimeNotifier.cs
...re/BackgroundServices/Notifications/ServerTimeNotifier.cs
+38
-0
Infrastructure.csproj
Clinics.Backend/Infrastructure/Infrastructure.csproj
+31
-0
NotificationHub.cs
...ackend/Infrastructure/NotificationsHub/NotificationHub.cs
+20
-0
package-lock.json
Clinics.Frontend/package-lock.json
+179
-4
package.json
Clinics.Frontend/package.json
+1
-0
app-routing.module.ts
Clinics.Frontend/src/app/app-routing.module.ts
+11
-0
app.module.ts
Clinics.Frontend/src/app/app.module.ts
+5
-1
signal-r.service.ts
Clinics.Frontend/src/app/notifications/signal-r.service.ts
+41
-0
test-signal-r.component.css
...rontend/src/app/test-signal-r/test-signal-r.component.css
+0
-0
test-signal-r.component.html
...ontend/src/app/test-signal-r/test-signal-r.component.html
+8
-0
test-signal-r.component.ts
...Frontend/src/app/test-signal-r/test-signal-r.component.ts
+26
-0
No files found.
Clinics.Backend/API/API.csproj
View file @
0d73b915
...
...
@@ -26,6 +26,7 @@
<ItemGroup>
<ProjectReference Include="..\Application\Application.csproj" />
<ProjectReference Include="..\Domain\Domain.csproj" />
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
<ProjectReference Include="..\Persistence\Persistence.csproj" />
<ProjectReference Include="..\Presentation\Presentation.csproj" />
</ItemGroup>
...
...
Clinics.Backend/API/Program.cs
View file @
0d73b915
...
...
@@ -3,6 +3,8 @@ using API.Options.JWT;
using
API.SeedDatabaseHelper
;
using
Application.Behaviors
;
using
FluentValidation
;
using
Infrastructure.BackgroundServices.Notifications
;
using
Infrastructure.NotificationsService
;
using
MediatR
;
using
Microsoft.AspNetCore.Authentication.JwtBearer
;
using
Microsoft.EntityFrameworkCore
;
...
...
@@ -12,6 +14,10 @@ using Persistence.Context;
var
builder
=
WebApplication
.
CreateBuilder
(
args
);
// Add services to the container.
#region Add Database context
// First, get database options
builder
.
Services
.
ConfigureOptions
<
DatabaseOptionsSetup
>();
...
...
@@ -35,7 +41,16 @@ builder.Services.AddDbContext<ClinicsDbContext>(
});
#endregion
// Add services to the container.
#region Add SignalR
builder
.
Services
.
AddSignalR
();
// Background services:
builder
.
Services
.
AddHostedService
<
ServerTimeNotifier
>();
#endregion
#region Add CORS
builder
.
Services
.
AddCors
();
#endregion
#region Link interfaces implemented in persistence
// Using Scrutor library
...
...
@@ -126,9 +141,17 @@ if (app.Environment.IsDevelopment())
app
.
UseHttpsRedirection
();
#region Map notification HUB
app
.
MapHub
<
NotificationHub
>(
"api/Notifications"
);
#endregion
#region CORS
// TODO: Configure allows
app
.
UseCors
(
policy
=>
policy
.
AllowAnyHeader
().
AllowAnyMethod
().
AllowAnyHeader
().
AllowAnyOrigin
());
app
.
UseCors
(
policy
=>
policy
.
AllowAnyHeader
().
AllowAnyMethod
().
AllowAnyHeader
()
.
AllowCredentials
().
SetIsOriginAllowed
(
origin
=>
true
));
#endregion
...
...
Clinics.Backend/Clinics.Backend.sln
View file @
0d73b915
...
...
@@ -19,7 +19,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Presentation", "Presentatio
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Persistence", "Persistence\Persistence.csproj", "{2B5111ED-7AB8-46E2-90F8-AF0C70265618}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API", "API\API.csproj", "{15B2AA13-EBBD-408B-A4B3-4BAB43D74267}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "API", "API\API.csproj", "{15B2AA13-EBBD-408B-A4B3-4BAB43D74267}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "Infrastructure\Infrastructure.csproj", "{4EB41743-695F-4822-87F6-E6F9B48A8E6B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
...
...
@@ -47,6 +49,10 @@ Global
{15B2AA13-EBBD-408B-A4B3-4BAB43D74267}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15B2AA13-EBBD-408B-A4B3-4BAB43D74267}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15B2AA13-EBBD-408B-A4B3-4BAB43D74267}.Release|Any CPU.Build.0 = Release|Any CPU
{4EB41743-695F-4822-87F6-E6F9B48A8E6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4EB41743-695F-4822-87F6-E6F9B48A8E6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EB41743-695F-4822-87F6-E6F9B48A8E6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EB41743-695F-4822-87F6-E6F9B48A8E6B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
...
...
@@ -59,6 +65,7 @@ Global
{CE41FA28-76D7-4DC0-A980-B953F87253F5} = {6FC36DEB-2BC3-4980-B46B-7E518DAF09BF}
{D04C0D6C-3FC9-4359-A017-DFCFA1475639} = {878AE2C9-3E34-4332-ACC0-E6B601085710}
{2B5111ED-7AB8-46E2-90F8-AF0C70265618} = {FDA56BCD-A53D-4BA1-A59D-3F44FA32DDD7}
{4EB41743-695F-4822-87F6-E6F9B48A8E6B} = {FDA56BCD-A53D-4BA1-A59D-3F44FA32DDD7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E9FC9252-1283-485F-8F84-3574CFA12633}
...
...
Clinics.Backend/Infrastructure/BackgroundServices/Notifications/ServerTimeNotifier.cs
0 → 100644
View file @
0d73b915
using
Infrastructure.NotificationsService
;
using
Microsoft.AspNetCore.SignalR
;
using
Microsoft.Extensions.Hosting
;
using
Microsoft.Extensions.Logging
;
namespace
Infrastructure.BackgroundServices.Notifications
;
public
class
ServerTimeNotifier
:
BackgroundService
{
private
static
readonly
TimeSpan
Period
=
TimeSpan
.
FromSeconds
(
3
);
#
region
CTOR
DI
private
readonly
ILogger
<
ServerTimeNotifier
>
_logger
;
private
readonly
IHubContext
<
NotificationHub
,
INotificationClient
>
_context
;
public
ServerTimeNotifier
(
ILogger
<
ServerTimeNotifier
>
logger
,
IHubContext
<
NotificationHub
,
INotificationClient
>
context
)
{
_logger
=
logger
;
_context
=
context
;
}
#
endregion
protected
override
async
Task
ExecuteAsync
(
CancellationToken
stoppingToken
)
{
using
var
timer
=
new
PeriodicTimer
(
Period
);
while
(!
stoppingToken
.
IsCancellationRequested
&&
await
timer
.
WaitForNextTickAsync
(
stoppingToken
))
{
var
dateTime
=
DateTime
.
Now
;
_logger
.
LogInformation
(
"Executing {Service} {Time}"
,
nameof
(
ServerTimeNotifier
),
dateTime
);
await
_context
.
Clients
.
All
.
ReceiveNotification
(
$"Server time =
{
dateTime
}
"
);
}
}
}
Clinics.Backend/Infrastructure/Infrastructure.csproj
0 → 100644
View file @
0d73b915
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.2" />
<PackageReference Include="MediatR" Version="12.4.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Scrutor" Version="4.2.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Application\Application.csproj" />
<ProjectReference Include="..\Domain\Domain.csproj" />
</ItemGroup>
</Project>
Clinics.Backend/Infrastructure/NotificationsHub/NotificationHub.cs
0 → 100644
View file @
0d73b915
using
Microsoft.AspNetCore.SignalR
;
namespace
Infrastructure.NotificationsService
;
public
class
NotificationHub
:
Hub
<
INotificationClient
>
{
public
override
async
Task
OnConnectedAsync
()
{
await
Clients
.
Client
(
Context
.
ConnectionId
).
ReceiveNotification
(
$"Connected successfully
{
Context
.
User
?.
Identity
?.
Name
}
"
);
await
base
.
OnConnectedAsync
();
}
}
public
interface
INotificationClient
{
Task
ReceiveNotification
(
string
message
);
}
\ No newline at end of file
Clinics.Frontend/package-lock.json
View file @
0d73b915
This diff is collapsed.
Click to expand it.
Clinics.Frontend/package.json
View file @
0d73b915
...
...
@@ -19,6 +19,7 @@
"@angular/platform-browser-dynamic"
:
"^18.1.0"
,
"@angular/router"
:
"^18.1.0"
,
"@fortawesome/fontawesome-free"
:
"^6.6.0"
,
"@microsoft/signalr"
:
"^8.0.7"
,
"@ng-bootstrap/ng-bootstrap"
:
"^17.0.0"
,
"@popperjs/core"
:
"^2.11.8"
,
"bootstrap"
:
"^5.3.2"
,
...
...
Clinics.Frontend/src/app/app-routing.module.ts
View file @
0d73b915
...
...
@@ -5,6 +5,7 @@ import { RoleGuard } from './services/authentication/guards/role-guard';
import
{
Roles
}
from
'./classes/Authentication/roles'
;
import
{
ForbiddenComponent
}
from
'./components/errors/forbidden/forbidden.component'
;
import
{
NotFoundComponent
}
from
'./components/errors/not-found/not-found.component'
;
import
{
TestSignalRComponent
}
from
'./test-signal-r/test-signal-r.component'
;
const
routes
:
Routes
=
[
{
...
...
@@ -25,6 +26,16 @@ const routes: Routes = [
canActivate
:
[
RoleGuard
],
data
:
{
role
:
Roles
.
NotRegistered
}
},
// #region Testing SignalR
{
path
:
'testing'
,
component
:
TestSignalRComponent
,
canActivate
:
[
RoleGuard
],
data
:
{
role
:
Roles
.
NotRegistered
}
},
// #endregion
// Everything else
{
path
:
'**'
,
...
...
Clinics.Frontend/src/app/app.module.ts
View file @
0d73b915
...
...
@@ -18,6 +18,8 @@ import { AuthenticationService } from './services/authentication/authentication.
import
{
AuthenticationInterceptor
}
from
'./services/authentication/interceptor/authentication.interceptor'
;
import
{
ForbiddenComponent
}
from
'./components/errors/forbidden/forbidden.component'
;
import
{
NotFoundComponent
}
from
'./components/errors/not-found/not-found.component'
;
import
{
TestSignalRComponent
}
from
'./test-signal-r/test-signal-r.component'
;
import
{
SignalRService
}
from
'./notifications/signal-r.service'
;
@
NgModule
({
...
...
@@ -39,6 +41,7 @@ import { NotFoundComponent } from './components/errors/not-found/not-found.compo
providers
:
[
AuthenticationService
,
{
provide
:
HTTP_INTERCEPTORS
,
useClass
:
AuthenticationInterceptor
,
multi
:
true
},
SignalRService
],
// components and directives that belong to this module
...
...
@@ -52,7 +55,8 @@ import { NotFoundComponent } from './components/errors/not-found/not-found.compo
HomeComponent
,
LoginFormComponent
,
ForbiddenComponent
,
NotFoundComponent
NotFoundComponent
,
TestSignalRComponent
],
// identifies the root component that Angular should
...
...
Clinics.Frontend/src/app/notifications/signal-r.service.ts
0 → 100644
View file @
0d73b915
import
{
Injectable
}
from
'@angular/core'
;
import
{
HubConnectionBuilder
}
from
'@microsoft/signalr'
;
import
*
as
config
from
'../../../config'
@
Injectable
({
providedIn
:
'root'
})
export
class
SignalRService
{
constructor
()
{
}
private
readonly
NOTIFICATIONS_ENDPOINT
:
string
=
`
${
config
.
apiUrl
}
/Notifications`
hubConnection
:
signalR
.
HubConnection
;
startConnection
():
void
{
this
.
hubConnection
=
new
HubConnectionBuilder
()
.
withUrl
(
this
.
NOTIFICATIONS_ENDPOINT
)
.
build
();
this
.
hubConnection
.
start
()
.
then
(()
=>
{
console
.
log
(
'Connected to signalR!'
)
})
.
catch
(
err
=>
console
.
error
(
'Error while starting connection: '
+
err
))
}
endConnection
():
void
{
if
(
this
.
hubConnection
)
{
this
.
hubConnection
.
stop
()
.
then
(()
=>
{
console
.
log
(
'disonnected from signalR!'
);
})
.
catch
(
err
=>
console
.
error
(
'Error while stopping connection: '
+
err
));
}
else
{
console
.
log
(
'No active connection to stop.'
);
}
}
}
\ No newline at end of file
Clinics.Frontend/src/app/test-signal-r/test-signal-r.component.css
0 → 100644
View file @
0d73b915
Clinics.Frontend/src/app/test-signal-r/test-signal-r.component.html
0 → 100644
View file @
0d73b915
<div>
<div
class=
"text-center"
>
<h2>
Notifications:
</h2>
<h3>
{{notification}}
</h3>
<button
(
click
)="
onClick
()"
class=
"btn btn-outline-danger"
>
Stop
</button>
</div>
</div>
\ No newline at end of file
Clinics.Frontend/src/app/test-signal-r/test-signal-r.component.ts
0 → 100644
View file @
0d73b915
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
SignalRService
}
from
'../notifications/signal-r.service'
;
@
Component
({
selector
:
'app-test-signal-r'
,
templateUrl
:
'./test-signal-r.component.html'
,
styleUrls
:
[
'./test-signal-r.component.css'
]
})
export
class
TestSignalRComponent
implements
OnInit
{
notification
:
string
=
''
;
constructor
(
private
signalR
:
SignalRService
){}
ngOnInit
():
void
{
this
.
signalR
.
startConnection
();
this
.
signalR
.
hubConnection
.
on
(
'ReceiveNotification'
,
(
message
)
=>
{
this
.
notification
=
message
;
})
}
onClick
():
void
{
this
.
signalR
.
endConnection
();
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment