diff --git a/AsbCloudWebApi/AsbCloudWebApi.csproj b/AsbCloudWebApi/AsbCloudWebApi.csproj index 5f231625..0d8f4806 100644 --- a/AsbCloudWebApi/AsbCloudWebApi.csproj +++ b/AsbCloudWebApi/AsbCloudWebApi.csproj @@ -2,7 +2,7 @@ net6.0 - true + true true $(NoWarn);1591 80899ceb-210f-4f19-ac56-aa90a5d666d4 @@ -14,6 +14,7 @@ + diff --git a/AsbCloudWebApi/Controllers/DrillTestController.cs b/AsbCloudWebApi/Controllers/DrillTestController.cs index bda32d6e..2d9585dc 100644 --- a/AsbCloudWebApi/Controllers/DrillTestController.cs +++ b/AsbCloudWebApi/Controllers/DrillTestController.cs @@ -5,6 +5,7 @@ using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; +using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -28,16 +29,15 @@ public class DrillTestController : ControllerBase private readonly IDrillTestRepository drillTestRepository; private readonly IWellService wellService; private readonly ITelemetryService telemetryService; - private readonly IHubContext telemetryHubContext; + private readonly IHubContext telemetryHubContext; - public string SignalRMethodGetDataName { get; protected set; } = "ReceiveDrilltestData"; public DrillTestController( IDrillTestReportService drillTestReportService, IDrillTestRepository drillTestRepository, IWellService wellService, ITelemetryService telemetryService, - IHubContext telemetryHubContext) + IHubContext telemetryHubContext) { this.drillTestReportService = drillTestReportService; this.drillTestRepository = drillTestRepository; @@ -71,7 +71,7 @@ public class DrillTestController : ControllerBase _ = Task.Run(async () => { var clients = telemetryHubContext.Clients.Group($"well_{idWell}"); - await clients.SendAsync(SignalRMethodGetDataName, dto); + await clients.ReceiveDrilltestData(dto, token); }, CancellationToken.None); return Ok(); diff --git a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapBaseController.cs b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapBaseController.cs index 9bb52f33..6dc1d7d6 100644 --- a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapBaseController.cs +++ b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapBaseController.cs @@ -9,6 +9,7 @@ using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; +using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -25,7 +26,7 @@ namespace AsbCloudWebApi.Controllers.ProcessMaps; public abstract class ProcessMapBaseController : ControllerBase where T : ProcessMapPlanBaseDto { - private readonly IHubContext telemetryHubContext; + private readonly IHubContext telemetryHubContext; private readonly ITelemetryService telemetryService; private readonly IWellService wellService; private readonly IUserRepository userRepository; @@ -36,7 +37,7 @@ public abstract class ProcessMapBaseController : ControllerBase IProcessMapPlanRepository repository, IUserRepository userRepository, ICrudRepository wellSectionRepository, - IHubContext telemetryHubContext, + IHubContext telemetryHubContext, ITelemetryService telemetryService) { this.wellService = wellService; @@ -204,7 +205,7 @@ public abstract class ProcessMapBaseController : ControllerBase await telemetryHubContext.Clients .Group($"{SignalRMethod}_{idWell}") - .SendAsync("UpdateProcessMap", dtos, cancellationToken); + .UpdateProcessMap(dtos, cancellationToken); } private async Task CheckIsExistsWellSectionTypeAsync(int idWellSectionType, CancellationToken cancellationToken) diff --git a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellDrillingController.cs b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellDrillingController.cs index 89963cfb..9f6812e6 100644 --- a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellDrillingController.cs +++ b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellDrillingController.cs @@ -10,6 +10,7 @@ using AsbCloudApp.Services; using AsbCloudApp.Services.ProcessMaps; using AsbCloudApp.Services.ProcessMaps.WellDrilling; using AsbCloudWebApi.SignalR; +using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; @@ -34,7 +35,7 @@ public class ProcessMapWellDrillingController : ProcessMapBaseController wellSectionRepository, - IHubContext telemetryHubContext, + IHubContext telemetryHubContext, ITelemetryService telemetryService) : base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService) { diff --git a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellReamController.cs b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellReamController.cs index f0f48e74..b54323d2 100644 --- a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellReamController.cs +++ b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellReamController.cs @@ -3,6 +3,7 @@ using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; +using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.SignalR; namespace AsbCloudWebApi.Controllers.ProcessMaps; @@ -16,7 +17,7 @@ public class ProcessMapWellReamController : ProcessMapBaseController repository, IUserRepository userRepository, ICrudRepository wellSectionRepository, - IHubContext telemetryHubContext, + IHubContext telemetryHubContext, ITelemetryService telemetryService) : base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService) { diff --git a/AsbCloudWebApi/Controllers/ReportController.cs b/AsbCloudWebApi/Controllers/ReportController.cs index 3386d505..c9f0c8d9 100644 --- a/AsbCloudWebApi/Controllers/ReportController.cs +++ b/AsbCloudWebApi/Controllers/ReportController.cs @@ -8,6 +8,7 @@ using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Requests; +using AsbCloudWebApi.SignalR.Clients; namespace AsbCloudWebApi.Controllers { @@ -21,10 +22,10 @@ namespace AsbCloudWebApi.Controllers private readonly IReportService reportService; private readonly FileService fileService; private readonly IWellService wellService; - private readonly IHubContext reportsHubContext; + private readonly IHubContext reportsHubContext; public ReportController(IReportService reportService, IWellService wellService, - FileService fileService, IHubContext reportsHubContext) + FileService fileService, IHubContext reportsHubContext) { this.reportService = reportService; this.fileService = fileService; @@ -57,13 +58,10 @@ namespace AsbCloudWebApi.Controllers return Forbid(); void HandleReportProgressAsync(object progress, string id) => - Task.Run(() => + Task.Run(async() => { - reportsHubContext.Clients.Group($"Report_{id}").SendAsync( - nameof(IReportHubClient.GetReportProgress), - progress, - token - ).ConfigureAwait(false); + await reportsHubContext.Clients.Group($"Report_{id}") + .GetReportProgress(progress, token); }, token); var id = reportService.EnqueueCreateReportWork(idWell, (int)idUser, diff --git a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs index a09fd6bf..57a97043 100644 --- a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs @@ -2,6 +2,7 @@ using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; +using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; @@ -23,22 +24,23 @@ namespace AsbCloudWebApi.Controllers.SAUB protected readonly IWellService wellService; private readonly ITelemetryService telemetryService; private readonly ITelemetryDataService telemetryDataService; - private readonly IHubContext telemetryHubContext; - - public string SignalRMethodGetDataName { get; protected set; } = "ReceiveData"; + protected readonly IHubContext telemetryHubContext; public TelemetryDataBaseController( ITelemetryService telemetryService, ITelemetryDataService telemetryDataService, IWellService wellService, - IHubContext telemetryHubContext) + IHubContext telemetryHubContext) { this.telemetryService = telemetryService; this.telemetryDataService = telemetryDataService; this.wellService = wellService; this.telemetryHubContext = telemetryHubContext; + } + protected abstract Task SignalRNotifyAsync(int idWell, IEnumerable dtos, CancellationToken token); + /// /// Принимает данные от разных систем по скважине /// @@ -55,8 +57,7 @@ namespace AsbCloudWebApi.Controllers.SAUB var idWell = telemetryService.GetIdWellByTelemetryUid(uid); if (idWell is not null && dtos.Any()) - _ = Task.Run(() => telemetryHubContext.Clients.Group($"well_{idWell}") - .SendAsync(SignalRMethodGetDataName, dtos), CancellationToken.None); + _ = Task.Run(() => SignalRNotifyAsync(idWell.Value, dtos, CancellationToken.None)); return Ok(); } @@ -75,7 +76,7 @@ namespace AsbCloudWebApi.Controllers.SAUB [Permission] public virtual async Task>> GetDataAsync(int idWell, DateTime begin = default, - int intervalSec = 600, + int intervalSec = 600, int approxPointsCount = 1024, //TODO: сделать cancellationToken обязательным CancellationToken token = default) diff --git a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataSaubController.cs b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataSaubController.cs index be694818..e3791655 100644 --- a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataSaubController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataSaubController.cs @@ -1,12 +1,14 @@ using AsbCloudApp.Data.SAUB; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; +using AsbCloudWebApi.SignalR.Clients; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; -using System.Threading.Tasks; -using System.Threading; using System; -using Microsoft.AspNetCore.Http; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers.SAUB { @@ -23,14 +25,13 @@ namespace AsbCloudWebApi.Controllers.SAUB ITelemetryService telemetryService, ITelemetryDataSaubService telemetryDataService, IWellService wellService, - IHubContext telemetryHubContext) + IHubContext telemetryHubContext) : base( telemetryService, telemetryDataService, wellService, telemetryHubContext) { - SignalRMethodGetDataName = "ReceiveDataSaub"; telemetryDataSaubService = telemetryDataService; } @@ -62,5 +63,10 @@ namespace AsbCloudWebApi.Controllers.SAUB var fileName = $"DataSaub idWell{idWell} {beginDate:yyyy-MM-DDTHH-mm} - {endDate:yyyy-MM-DDTHH-mm}.zip"; return File(stream, "application/octet-stream", fileName); } + + protected override Task SignalRNotifyAsync(int idWell, IEnumerable dtos, CancellationToken token) + { + return telemetryHubContext.Clients.Group($"well_{idWell}").ReceiveDataSaub(dtos, token); + } } } diff --git a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataSpinController.cs b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataSpinController.cs index c8b55cc6..9c81af02 100644 --- a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataSpinController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataSpinController.cs @@ -1,8 +1,12 @@ using AsbCloudApp.Data.SAUB; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; +using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers.SAUB { @@ -17,14 +21,17 @@ namespace AsbCloudWebApi.Controllers.SAUB ITelemetryService telemetryService, ITelemetryDataService telemetryDataService, IWellService wellService, - IHubContext telemetryHubContext) + IHubContext telemetryHubContext) : base( telemetryService, telemetryDataService, wellService, telemetryHubContext) + {} + + protected override Task SignalRNotifyAsync(int idWell, IEnumerable dtos, CancellationToken token) { - SignalRMethodGetDataName = "ReceiveDataSpin"; + return telemetryHubContext.Clients.Group($"well_{idWell}").ReceiveDataSpin(dtos, token); } } } diff --git a/AsbCloudWebApi/Conventions/ApiExplorerGroupPerVersionConvention.cs b/AsbCloudWebApi/Conventions/ApiExplorerGroupPerVersionConvention.cs new file mode 100644 index 00000000..69a912cf --- /dev/null +++ b/AsbCloudWebApi/Conventions/ApiExplorerGroupPerVersionConvention.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Mvc.ApplicationModels; +using System.Linq; + +namespace AsbCloudWebApi.Conventions +{ + public class ApiExplorerGroupPerVersionConvention : IControllerModelConvention + { + public void Apply(ControllerModel controller) + { + controller.ApiExplorer.GroupName = "v1"; + } + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/DependencyInjection.cs b/AsbCloudWebApi/DependencyInjection.cs index 998212b2..788c661d 100644 --- a/AsbCloudWebApi/DependencyInjection.cs +++ b/AsbCloudWebApi/DependencyInjection.cs @@ -19,6 +19,7 @@ using AsbCloudWebApi.SignalR; using AsbCloudWebApi.SignalR.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.OpenApi.Any; +using Swashbuckle.AspNetCore.SwaggerGen; namespace AsbCloudWebApi { @@ -46,6 +47,7 @@ namespace AsbCloudWebApi }); c.SwaggerDoc("v1", new OpenApiInfo { Title = "ASB cloud web api", Version = "v1" }); + c.SwaggerDoc("signalr", new OpenApiInfo { Title = "SignalR client methods", Version = "signalr" }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'", @@ -78,6 +80,13 @@ namespace AsbCloudWebApi var includeControllerXmlComment = true; c.IncludeXmlComments(xmlPath, includeControllerXmlComment); c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "AsbCloudApp.xml"), includeControllerXmlComment); + + c.AddSignalRSwaggerGen(options => { + options.DisplayInDocument("signalr"); + options.UseHubXmlCommentsSummaryAsTagDescription = true; + options.UseHubXmlCommentsSummaryAsTag = true; + options.UseXmlComments(xmlPath); + }); }); } diff --git a/AsbCloudWebApi/Docs/Nginx/nginx.conf b/AsbCloudWebApi/Docs/Nginx/nginx.conf new file mode 100644 index 00000000..f33640db --- /dev/null +++ b/AsbCloudWebApi/Docs/Nginx/nginx.conf @@ -0,0 +1,161 @@ +user www-data; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + proxy_cache_path /home/asb/web-content/cache keys_zone=map-cache:1024m; + + server{ + listen 5085; + charset UTF-8; + + location / { + root /home/asb/public_files; + autoindex on; + autoindex_exact_size off; + autoindex_format html; + autoindex_localtime on; + } + } + + server { + listen 5090; + proxy_buffering on; + proxy_buffer_size 1M; + proxy_buffers 48 1M; + proxy_cache_lock on; + proxy_cache_lock_age 5s; + proxy_http_version 1.1; + proxy_cache_valid 200 61d; + proxy_cache_use_stale error timeout; + + + #путь до папки с ui-проектом в файловой системе + root /home/asb/AsbCloudUI; + index index.html; + + location / { + try_files $uri /index.html; + } + + #запрос, начинающийся с /api или /auth или /hubs + location ~ ^/(api|auth|hubs)/ { + + #адрес, на который будут пересылаться запросы от клиентов + proxy_pass http://127.0.0.1:5000; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /swagger/ { + proxy_pass http://127.0.0.1:5000/swagger/; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /favicon.ico { + alias /home/asb/web-content/images/favicon.ico; + add_header Cache-Control "public"; + expires 4h; + } + + location /config.json { + alias /home/asb/web-content/config.json; + add_header Cache-Control "public"; + expires 4h; + } + + location /images/ { + root /home/asb/web-content; + add_header Cache-Control "public"; + expires 4h; + } + + location /map/a/ { + proxy_pass https://a.tile.openstreetmap.org/; + proxy_cache map-cache; + proxy_cache_key $request_uri; + } + location /map/b/ { + proxy_pass https://b.tile.openstreetmap.org/; + proxy_cache map-cache; + proxy_cache_key $request_uri; + } + location /map/c/ { + proxy_pass https://c.tile.openstreetmap.org/; + proxy_cache map-cache; + proxy_cache_key $request_uri; + } + location /map/ { + proxy_pass https://b.tile.openstreetmap.org/; + proxy_cache map-cache; + proxy_cache_key $request_uri; + } + } + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} diff --git a/AsbCloudWebApi/Middlewares/RequerstTrackerMiddleware.cs b/AsbCloudWebApi/Middlewares/RequerstTrackerMiddleware.cs index e8910b5d..392b3bca 100644 --- a/AsbCloudWebApi/Middlewares/RequerstTrackerMiddleware.cs +++ b/AsbCloudWebApi/Middlewares/RequerstTrackerMiddleware.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; -using Org.BouncyCastle.Asn1.Ocsp; +using System.Linq; using System.Threading.Tasks; namespace AsbCloudWebApi.Middlewares @@ -18,10 +18,11 @@ namespace AsbCloudWebApi.Middlewares public async Task InvokeAsync(HttpContext context) { var service = context.RequestServices.GetRequiredService(); + var clientIp = context.Request.Headers["X-Real-IP"].FirstOrDefault(); var requestLog = new AsbCloudApp.Data.RequestLogDto { UserLogin = context.User.Identity?.Name ?? string.Empty, - UserIp = context.Connection?.RemoteIpAddress?.ToString(), + UserIp = clientIp ?? context.Connection?.RemoteIpAddress?.ToString(), RequestMethod = context.Request.Method, RequestPath = context.Request.Path.Value, RequestContentLength = context.Request.ContentLength, diff --git a/AsbCloudWebApi/SignalR/BaseHub.cs b/AsbCloudWebApi/SignalR/BaseHub.cs index c351ccc4..28de8ab5 100644 --- a/AsbCloudWebApi/SignalR/BaseHub.cs +++ b/AsbCloudWebApi/SignalR/BaseHub.cs @@ -1,9 +1,10 @@ +using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; namespace AsbCloudWebApi.SignalR; -public abstract class BaseHub : Hub +public abstract class BaseHub : Hub where T : class { public virtual Task AddToGroup(string groupName) => Groups.AddToGroupAsync(Context.ConnectionId, groupName); @@ -11,9 +12,3 @@ public abstract class BaseHub : Hub public virtual Task RemoveFromGroup(string groupName) => Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName); } - -public abstract class BaseHub : BaseHub - where T : class -{ - -} \ No newline at end of file diff --git a/AsbCloudWebApi/SignalR/Clients/INotificationHubClient.cs b/AsbCloudWebApi/SignalR/Clients/INotificationHubClient.cs new file mode 100644 index 00000000..09c36851 --- /dev/null +++ b/AsbCloudWebApi/SignalR/Clients/INotificationHubClient.cs @@ -0,0 +1,23 @@ +using AsbCloudWebApi.SignalR.Messages; +using SignalRSwaggerGen.Attributes; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.SignalR.Clients +{ + /// + /// Hub по работе с уведомлениями + /// + [SignalRHub] + public interface INotificationHubClient + { + /// + /// Отправка клиенту сообщения с уведомлением. + /// Для подписки на метод необходимо отправить connectionId + /// + /// сообщение с уведомлением + /// + /// + Task ReceiveNotifications(NotificationMessage message, CancellationToken token); + } +} diff --git a/AsbCloudWebApi/SignalR/Clients/IReportHubClient.cs b/AsbCloudWebApi/SignalR/Clients/IReportHubClient.cs new file mode 100644 index 00000000..dde7da3f --- /dev/null +++ b/AsbCloudWebApi/SignalR/Clients/IReportHubClient.cs @@ -0,0 +1,22 @@ +using SignalRSwaggerGen.Attributes; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.SignalR.Clients +{ + /// + /// Hub по работе с отчетами + /// + [SignalRHub] + public interface IReportHubClient + { + /// + /// Отправка клиенту сообщения о статусе формирования отчета. + /// Для подписки на метод необходимо отправить сообщение в формате $"Report_{id}" + /// + /// статус формирования отчета + /// + /// + Task GetReportProgress(object progress, CancellationToken token); + } +} diff --git a/AsbCloudWebApi/SignalR/Clients/ITelemetryHubClient.cs b/AsbCloudWebApi/SignalR/Clients/ITelemetryHubClient.cs new file mode 100644 index 00000000..3e82572b --- /dev/null +++ b/AsbCloudWebApi/SignalR/Clients/ITelemetryHubClient.cs @@ -0,0 +1,52 @@ +using AsbCloudApp.Data.SAUB; +using SignalRSwaggerGen.Attributes; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.SignalR.Clients +{ + /// + /// Hub по работе с телеметрией + /// + [SignalRHub] + public interface ITelemetryHubClient + { + /// + /// Отправка клиенту уведомления о доставке с панели drill test данных. + /// Для подписки на метод необходимо отправить сообщение в формате $"well_{idWell}" + /// + /// + /// + /// + Task ReceiveDrilltestData(DrillTestDto dto, CancellationToken token); + + /// + /// + /// + /// + /// + /// + Task UpdateProcessMap(IEnumerable dtos, CancellationToken token); + + /// + /// Отправка сауб-данных клиенту. + /// Для подписки на метод необходимо отправить сообщение в формате $"well_{idWell}" + /// + /// + /// + /// + Task ReceiveDataSaub(IEnumerable dtos, CancellationToken token); + + /// + /// Отправка спин-данных клиенту. + /// Для подписки на метод необходимо отправить сообщение в формате $"well_{idWell}" + /// + /// + /// + /// + Task ReceiveDataSpin(IEnumerable dtos, CancellationToken token); + + } +} diff --git a/AsbCloudWebApi/SignalR/Clients/IWellInfoHubClient.cs b/AsbCloudWebApi/SignalR/Clients/IWellInfoHubClient.cs new file mode 100644 index 00000000..110143ed --- /dev/null +++ b/AsbCloudWebApi/SignalR/Clients/IWellInfoHubClient.cs @@ -0,0 +1,23 @@ +using AsbCloudApp.Data; +using SignalRSwaggerGen.Attributes; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.SignalR.Clients +{ + /// + /// Hub по работе с информацией о скважине + /// + [SignalRHub] + public interface IWellInfoHubClient + { + /// + /// Отправка клиенту сообщения об обновлении информации о скважине + /// Для подписки на метод необходимо отправить сообщение в формате $"well_info_{idWell}" + /// + /// информация о скважине + /// + /// + Task UpdateWellInfo(object wellInfo, CancellationToken token); + } +} diff --git a/AsbCloudWebApi/SignalR/IReportHubClient.cs b/AsbCloudWebApi/SignalR/IReportHubClient.cs deleted file mode 100644 index 4eb9581f..00000000 --- a/AsbCloudWebApi/SignalR/IReportHubClient.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AsbCloudWebApi.SignalR -{ - public interface IReportHubClient - { - float GetReportProgress(float progress); - } -} diff --git a/AsbCloudWebApi/SignalR/NotificationHub.cs b/AsbCloudWebApi/SignalR/NotificationHub.cs index b85ce74b..4deea974 100644 --- a/AsbCloudWebApi/SignalR/NotificationHub.cs +++ b/AsbCloudWebApi/SignalR/NotificationHub.cs @@ -2,6 +2,7 @@ using System; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Services.Notifications; +using AsbCloudWebApi.SignalR.Clients; using AsbCloudWebApi.SignalR.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -9,7 +10,7 @@ using Microsoft.AspNetCore.Mvc; namespace AsbCloudWebApi.SignalR; [Authorize] -public class NotificationHub : BaseHub +public class NotificationHub : BaseHub { private readonly ConnectionManagerService connectionManagerService; private readonly NotificationService notificationService; diff --git a/AsbCloudWebApi/SignalR/ReportsHub.cs b/AsbCloudWebApi/SignalR/ReportsHub.cs index 66292d05..bb0da640 100644 --- a/AsbCloudWebApi/SignalR/ReportsHub.cs +++ b/AsbCloudWebApi/SignalR/ReportsHub.cs @@ -1,7 +1,7 @@ using AsbCloudApp.Data; using AsbCloudInfrastructure.Background; +using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.SignalR; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -10,7 +10,10 @@ namespace AsbCloudWebApi.SignalR { // SignalR manual: // https://docs.microsoft.com/ru-ru/aspnet/core/signalr/introduction?view=aspnetcore-5.0 - + //[SignalRHub] + /// + /// ReportsHub + /// [Authorize] public class ReportsHub : BaseHub { @@ -21,6 +24,11 @@ namespace AsbCloudWebApi.SignalR this.backgroundWorker = backgroundWorker; } + /// + /// Добавление в группу, отправка данных о формировании отчета + /// + /// + /// public override async Task AddToGroup(string groupName) { await base.AddToGroup(groupName); @@ -34,19 +42,14 @@ namespace AsbCloudWebApi.SignalR Progress = 0f, }; - var state = work?.CurrentState; + var state = work?.CurrentState; if (state is not null) { progress.Operation = state.State; progress.Progress = (float)state.Progress; } - await Clients.Group(groupName).SendAsync( - nameof(IReportHubClient.GetReportProgress), - progress, - CancellationToken.None - ); - + await Clients.Group(groupName).GetReportProgress(progress, CancellationToken.None); } } } diff --git a/AsbCloudWebApi/SignalR/Services/NotificationPublisher.cs b/AsbCloudWebApi/SignalR/Services/NotificationPublisher.cs index 1f6f4f67..6799e71d 100644 --- a/AsbCloudWebApi/SignalR/Services/NotificationPublisher.cs +++ b/AsbCloudWebApi/SignalR/Services/NotificationPublisher.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Repositories; +using AsbCloudWebApi.SignalR.Clients; using AsbCloudWebApi.SignalR.Messages; using Microsoft.AspNetCore.SignalR; @@ -12,11 +13,11 @@ namespace AsbCloudWebApi.SignalR.Services; public class NotificationPublisher { private readonly ConnectionManagerService connectionManagerService; - private readonly IHubContext notificationHubContext; + private readonly IHubContext notificationHubContext; private readonly INotificationRepository notificationRepository; public NotificationPublisher(ConnectionManagerService connectionManagerService, - IHubContext notificationHubContext, + IHubContext notificationHubContext, INotificationRepository notificationRepository) { this.connectionManagerService = connectionManagerService; @@ -70,8 +71,6 @@ public class NotificationPublisher CancellationToken cancellationToken) { await notificationHubContext.Clients.Client(connectionId) - .SendAsync("receiveNotifications", - message, - cancellationToken); + .ReceiveNotifications(message, cancellationToken); } } \ No newline at end of file diff --git a/AsbCloudWebApi/SignalR/TelemetryHub.cs b/AsbCloudWebApi/SignalR/TelemetryHub.cs index 9b7fd59d..69b6c628 100644 --- a/AsbCloudWebApi/SignalR/TelemetryHub.cs +++ b/AsbCloudWebApi/SignalR/TelemetryHub.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authorization; +using AsbCloudWebApi.SignalR.Clients; +using Microsoft.AspNetCore.Authorization; namespace AsbCloudWebApi.SignalR { @@ -6,7 +7,7 @@ namespace AsbCloudWebApi.SignalR // https://docs.microsoft.com/ru-ru/aspnet/core/signalr/introduction?view=aspnetcore-5.0 [Authorize] - public class TelemetryHub : BaseHub + public class TelemetryHub : BaseHub { } diff --git a/AsbCloudWebApi/SignalR/WellInfoHub.cs b/AsbCloudWebApi/SignalR/WellInfoHub.cs index 677b4f64..553923fd 100644 --- a/AsbCloudWebApi/SignalR/WellInfoHub.cs +++ b/AsbCloudWebApi/SignalR/WellInfoHub.cs @@ -4,17 +4,18 @@ using AsbCloudApp.IntegrationEvents; using AsbCloudApp.IntegrationEvents.Interfaces; using AsbCloudApp.Services; using AsbCloudInfrastructure.Services; +using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.SignalR; namespace AsbCloudWebApi.SignalR; -public class WellInfoHub : BaseHub, IIntegrationEventHandler +public class WellInfoHub : BaseHub, IIntegrationEventHandler { - private readonly IHubContext hubContext; + private readonly IHubContext hubContext; private readonly IWellService wellService; private readonly WellInfoService wellInfoService; - public WellInfoHub(IHubContext hubContext, + public WellInfoHub(IHubContext hubContext, IWellService wellService, WellInfoService wellInfoService) { @@ -34,8 +35,6 @@ public class WellInfoHub : BaseHub, IIntegrationEventHandler w.Id == well.Id); await hubContext.Clients.Group($"well_info_{integrationEvent.IdWell}") - .SendAsync(method, new + .UpdateWellInfo(new { Well = well, WellInfo = wellInfo diff --git a/AsbCloudWebApi/Startup.cs b/AsbCloudWebApi/Startup.cs index f04a53d1..c7138dba 100644 --- a/AsbCloudWebApi/Startup.cs +++ b/AsbCloudWebApi/Startup.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.ResponseCompression; +using AsbCloudWebApi.Conventions; namespace AsbCloudWebApi { @@ -108,6 +109,10 @@ namespace AsbCloudWebApi options.EnableForHttps = true; options.Providers.Add(); }); + + services.AddMvc(c => + c.Conventions.Add(new ApiExplorerGroupPerVersionConvention()) + ); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) @@ -116,6 +121,7 @@ namespace AsbCloudWebApi app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "V1"); + c.SwaggerEndpoint("/swagger/signalr/swagger.json", "signalr"); c.EnablePersistAuthorization(); c.EnableFilter(); c.DisplayOperationId(); @@ -158,11 +164,6 @@ namespace AsbCloudWebApi endpoints.MapHub("/hubs/telemetry"); endpoints.MapHub("/hubs/reports"); }); - - app.UseSpa(spa => - { - spa.Options.SourcePath = "wwwroot"; - }); } } }