| public string Id { get; set; } | public string Id { get; set; } | ||||
| [ProtoMember(2)] | [ProtoMember(2)] | ||||
| public string Token { get; set; } | public string Token { get; set; } | ||||
| [ProtoMember(3)] | |||||
| public string RefreshToken{ get; set; } | |||||
| } | } | ||||
| } | } |
| [ProtoContract] | [ProtoContract] | ||||
| public class VoidMessage | public class VoidMessage | ||||
| { | { | ||||
| [ProtoMember(1)] | |||||
| public string InsertedId { get; set; } | |||||
| } | } | ||||
| } | } |
| Task<VoidMessage> DeleteTrackAsync(DbRequestMessage id); | Task<VoidMessage> DeleteTrackAsync(DbRequestMessage id); | ||||
| Task<VoidMessage> SaveUserAsync(UserResponse user); | Task<VoidMessage> SaveUserAsync(UserResponse user); | ||||
| Task<VoidMessage> DeleteUserAsync(DbRequestMessage user); | Task<VoidMessage> DeleteUserAsync(DbRequestMessage user); | ||||
| Task<VoidMessage> UpdateTokenAsync (UserResponse user); | |||||
| } | } | ||||
| } | } |
| [BsonRepresentation(BsonType.ObjectId)] | [BsonRepresentation(BsonType.ObjectId)] | ||||
| public string Id { get; set; } | public string Id { get; set; } | ||||
| public string Token { get; set; } | public string Token { get; set; } | ||||
| public string RefreshToken { get; set; } | |||||
| } | } | ||||
| } | } |
| { | |||||
| { | |||||
| "iisSettings": { | "iisSettings": { | ||||
| "windowsAuthentication": false, | "windowsAuthentication": false, | ||||
| "anonymousAuthentication": true, | "anonymousAuthentication": true, | ||||
| "profiles": { | "profiles": { | ||||
| "IIS Express": { | "IIS Express": { | ||||
| "commandName": "IISExpress", | "commandName": "IISExpress", | ||||
| "launchBrowser": true, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "environmentVariables": { | "environmentVariables": { | ||||
| "ASPNETCORE_ENVIRONMENT": "Development" | "ASPNETCORE_ENVIRONMENT": "Development" | ||||
| } | |||||
| }, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}" | |||||
| }, | }, | ||||
| "IdentityProvider": { | "IdentityProvider": { | ||||
| "commandName": "Project", | "commandName": "Project", | ||||
| "dotnetRunMessages": "true", | |||||
| "launchBrowser": true, | "launchBrowser": true, | ||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "applicationUrl": "https://localhost:5001;http://localhost:5000", | |||||
| "environmentVariables": { | "environmentVariables": { | ||||
| "ASPNETCORE_ENVIRONMENT": "Development" | "ASPNETCORE_ENVIRONMENT": "Development" | ||||
| } | |||||
| }, | |||||
| "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", | |||||
| "applicationUrl": "https://localhost:5001;http://localhost:5000", | |||||
| "dotnetRunMessages": "true" | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } |
| public async Task<UserResponse> GetTokenByIdAsync(DbRequestMessage request) | public async Task<UserResponse> GetTokenByIdAsync(DbRequestMessage request) | ||||
| { | { | ||||
| UserModel user = await _userCollection.Find(u => u.Id == request.Id).FirstOrDefaultAsync(); | UserModel user = await _userCollection.Find(u => u.Id == request.Id).FirstOrDefaultAsync(); | ||||
| return new UserResponse | |||||
| { | |||||
| Id = user.Id, | |||||
| Token = user.Token | |||||
| }; | |||||
| if (user != null) | |||||
| return new UserResponse | |||||
| { | |||||
| Id = user.Id, | |||||
| Token = user.Token | |||||
| }; | |||||
| else return new UserResponse(); | |||||
| } | } | ||||
| public async Task<TrackResponse> GetTrackByUserAsync(DbRequestMessage request) | public async Task<TrackResponse> GetTrackByUserAsync(DbRequestMessage request) | ||||
| { | { | ||||
| TrackModel trackModel = new() | TrackModel trackModel = new() | ||||
| { | { | ||||
| Id = track.Id, | |||||
| Title = track.Title, | Title = track.Title, | ||||
| Album = track.Album, | Album = track.Album, | ||||
| Artist = track.Artist, | Artist = track.Artist, | ||||
| TrackId = track.TrackId | TrackId = track.TrackId | ||||
| }; | }; | ||||
| //first check if there's already a song in the db, if yes, update the row | //first check if there's already a song in the db, if yes, update the row | ||||
| var song = await _trackCollection.Find(x => x.UserId == track.UserId).AnyAsync(); | |||||
| bool song = await _trackCollection.Find(x => x.UserId == track.UserId).AnyAsync(); | |||||
| if (song) await _trackCollection.ReplaceOneAsync(x => x.UserId == track.UserId, trackModel); | |||||
| if (song) await _trackCollection.DeleteOneAsync(s => s.UserId == track.UserId); | |||||
| else await _trackCollection.InsertOneAsync(trackModel); | |||||
| await _trackCollection.InsertOneAsync(trackModel); | |||||
| return new VoidMessage(); | |||||
| return new VoidMessage() { InsertedId = trackModel.Id }; | |||||
| } | } | ||||
| public async Task<VoidMessage> SaveUserAsync(UserResponse userRequest) | public async Task<VoidMessage> SaveUserAsync(UserResponse userRequest) | ||||
| { | { | ||||
| bool user = await _userCollection.Find(x => x.Id == userRequest.Id).AnyAsync(); | bool user = await _userCollection.Find(x => x.Id == userRequest.Id).AnyAsync(); | ||||
| if (!user) await _userCollection.InsertOneAsync(new UserModel | |||||
| UserModel tempUser = new() | |||||
| { | { | ||||
| Token = userRequest.Token | |||||
| }); | |||||
| return new VoidMessage(); | |||||
| Token = userRequest.Token, | |||||
| RefreshToken = userRequest.RefreshToken | |||||
| }; | |||||
| if (!user) await _userCollection.InsertOneAsync(tempUser); | |||||
| return new VoidMessage() { InsertedId = tempUser.Id }; | |||||
| } | } | ||||
| public async Task<VoidMessage> DeleteTrackAsync(DbRequestMessage request) | public async Task<VoidMessage> DeleteTrackAsync(DbRequestMessage request) | ||||
| { | { | ||||
| return new VoidMessage(); | return new VoidMessage(); | ||||
| } | } | ||||
| public async Task<VoidMessage> UpdateTokenAsync(UserResponse user) | |||||
| { | |||||
| UserModel dbUser = await _userCollection.Find(x => x.Id == user.Id).FirstOrDefaultAsync(); | |||||
| if (dbUser.Id != null) | |||||
| { | |||||
| dbUser.Token = user.Token; | |||||
| dbUser.RefreshToken = user.RefreshToken; | |||||
| await _userCollection.ReplaceOneAsync(x => x.Id == user.Id, dbUser); | |||||
| } | |||||
| return new VoidMessage | |||||
| { | |||||
| InsertedId = dbUser.Id | |||||
| }; | |||||
| } | |||||
| } | } | ||||
| } | } |
| @page "/callback" | @page "/callback" | ||||
| @using GrpcShared.DTO | |||||
| @using GrpcShared.DTO.Db | |||||
| @using NemAnBlazor.Services.Interfaces | @using NemAnBlazor.Services.Interfaces | ||||
| @inject NavigationManager NavigationMgr | @inject NavigationManager NavigationMgr | ||||
| @inject IAuthClientService AuthService | @inject IAuthClientService AuthService | ||||
| @inject Blazored.LocalStorage.ILocalStorageService localStorage | @inject Blazored.LocalStorage.ILocalStorageService localStorage | ||||
| @inject IIdentityClientService identityService | |||||
| <PageTitle>Redirecting...</PageTitle> | <PageTitle>Redirecting...</PageTitle> | ||||
| //if (response.access_token == null) NavigationMgr.NavigateTo("/"); | //if (response.access_token == null) NavigationMgr.NavigateTo("/"); | ||||
| //store access token in local storage | //store access token in local storage | ||||
| await localStorage.SetItemAsync("token", response.AccessToken); | |||||
| await localStorage.SetItemAsync("refresh_token", response.RefreshToken); | |||||
| //await localStorage.SetItemAsync("token", response.AccessToken); | |||||
| //await localStorage.SetItemAsync("refresh_token", response.RefreshToken); | |||||
| //UserResponse user = new(); | |||||
| //await identityService.SaveUserAsync(new GrpcShared.DTO.Db.UserResponse()); | |||||
| string userId = await localStorage.GetItemAsync<string>("user_info"); | |||||
| if(userId == null) | |||||
| { | |||||
| VoidMessage userRes = await identityService.SaveUserAsync(new GrpcShared.DTO.Db.UserResponse { RefreshToken = response.RefreshToken , Token = response.AccessToken}); | |||||
| if (userRes.InsertedId != null) | |||||
| await localStorage.SetItemAsync<string>("user_info", userRes.InsertedId); | |||||
| } | |||||
| //redirect to home | //redirect to home | ||||
| NavigationMgr.NavigateTo("/home"); | NavigationMgr.NavigateTo("/home"); | ||||
| } | } |
| @inject Blazored.LocalStorage.ILocalStorageService localStorage | @inject Blazored.LocalStorage.ILocalStorageService localStorage | ||||
| @inject ITrackClientService SearchService | @inject ITrackClientService SearchService | ||||
| @inject IAuthClientService AuthService | @inject IAuthClientService AuthService | ||||
| @inject IIdentityClientService identityService | |||||
| <PageTitle>Search</PageTitle> | <PageTitle>Search</PageTitle> | ||||
| private async Task Click() | private async Task Click() | ||||
| { | { | ||||
| var token = await localStorage.GetItemAsync<string>("token"); | |||||
| string refreshT = await localStorage.GetItemAsync<string>("refresh_token"); | |||||
| var userInfo = await localStorage.GetItemAsync<string>("user_info"); | |||||
| TokenMessage tokenM = new TokenMessage { Token = token, RefreshToken = refreshT }; | |||||
| var user = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage | |||||
| { | |||||
| Id = userInfo | |||||
| }); | |||||
| TokenMessage tokenM = new TokenMessage { Token = user.Token, RefreshToken = user.RefreshToken }; | |||||
| SearchRequest request = new() { Query = "aitch", Type = "track", Token = token }; | |||||
| SearchRequest request = new() { Query = "aitch", Type = "track", Token = user.Token }; | |||||
| try | try | ||||
| { | { | ||||
| if (searchResponse.ResponseMsg == System.Net.HttpStatusCode.Unauthorized) | if (searchResponse.ResponseMsg == System.Net.HttpStatusCode.Unauthorized) | ||||
| { | { | ||||
| string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, tokenM, localStorage); | |||||
| token = tempToken == null ? token : tempToken; | |||||
| string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, tokenM, user, localStorage, identityService); | |||||
| } | } | ||||
| } | } | ||||
| catch (RpcException e) | catch (RpcException e) |
| @page "/home" | @page "/home" | ||||
| @using Grpc.Core | @using Grpc.Core | ||||
| @using GrpcShared.DTO | @using GrpcShared.DTO | ||||
| @using GrpcShared.DTO.Db | |||||
| @using GrpcShared.DTO.Track | @using GrpcShared.DTO.Track | ||||
| @using NemAnBlazor.Services.Interfaces | @using NemAnBlazor.Services.Interfaces | ||||
| @using System.Net | @using System.Net | ||||
| @inject IStatsClientService spotifyService | @inject IStatsClientService spotifyService | ||||
| @inject ITrackClientService trackService | @inject ITrackClientService trackService | ||||
| @inject IAuthClientService AuthService | @inject IAuthClientService AuthService | ||||
| @inject NavigationManager NavigationMgr | |||||
| @inject IIdentityClientService identityService | @inject IIdentityClientService identityService | ||||
| <h3>Home</h3> | <h3>Home</h3> | ||||
| protected override async Task OnInitializedAsync() | protected override async Task OnInitializedAsync() | ||||
| { | { | ||||
| CurrentTrackResponse track; | CurrentTrackResponse track; | ||||
| string tokenS = await localStorage.GetItemAsync<string>("token"); | |||||
| string refreshT = await localStorage.GetItemAsync<string>("refresh_token"); | |||||
| string tokenS = "", refreshT = ""; | |||||
| string userId = await localStorage.GetItemAsync<string>("user_info"); | |||||
| //tokenS = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN"; | |||||
| TokenMessage token = new TokenMessage { Token = tokenS, RefreshToken = refreshT }; | |||||
| if (userId != null) | |||||
| { | |||||
| //get token from identity | |||||
| var userResponse = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage { Id = userId }); | |||||
| if (userResponse != null) | |||||
| { | |||||
| tokenS = userResponse.Token; | |||||
| refreshT = userResponse.RefreshToken; | |||||
| } | |||||
| else { | |||||
| await localStorage.RemoveItemAsync("user_info"); | |||||
| NavigationMgr.NavigateTo("/"); | |||||
| } | |||||
| } | |||||
| //tokenS = "BQBMgFm6jnFNWWeZEMGIRP_f-ENPid7Kw8JubAyuWAe4JK0S1DPFGlaAdZ_Fey6ePkCnz8-cqC0oyRmrciWUy5ISUTQKDe8PTQn4iBRMYCgM0n4GnS1xAErHJcm4Vpu2TAngk-4vQUOfTQRcedNTfCaHKP4uFJgTlTI7JHGrtB-_EZLnFcZ2OQe31oFQIJ1wM3ZtvwnN"; | |||||
| TokenMessage token = new() { Token = tokenS, RefreshToken = refreshT }; | |||||
| UserResponse user = new() { Id = userId, RefreshToken = refreshT }; | |||||
| try | try | ||||
| { | { | ||||
| track = await spotifyService.GetCurrentlyPlayingTrack(token); | track = await spotifyService.GetCurrentlyPlayingTrack(token); | ||||
| //if token expired, refresh it | //if token expired, refresh it | ||||
| if (track.ResponseMsg == System.Net.HttpStatusCode.Unauthorized) | if (track.ResponseMsg == System.Net.HttpStatusCode.Unauthorized) | ||||
| { | { | ||||
| string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, token, localStorage); | |||||
| string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, token, user, localStorage, identityService); | |||||
| tokenS = tempToken == null ? tokenS : tempToken; | tokenS = tempToken == null ? tokenS : tempToken; | ||||
| //if refreshed token is null, that means that refresh token was invalid, so you should redirect to login | //if refreshed token is null, that means that refresh token was invalid, so you should redirect to login | ||||
| } | } | ||||
| if (items.ResponseMsg == System.Net.HttpStatusCode.Unauthorized) | if (items.ResponseMsg == System.Net.HttpStatusCode.Unauthorized) | ||||
| { | { | ||||
| string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, token, localStorage); | |||||
| string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, token, user, localStorage, identityService); | |||||
| tokenS = tempToken == null ? tokenS : tempToken; | tokenS = tempToken == null ? tokenS : tempToken; | ||||
| } | } | ||||
| } | } | ||||
| throw; | throw; | ||||
| } | } | ||||
| //await identityService.SaveUserAsync(new GrpcShared.DTO.Db.UserResponse | |||||
| // { | |||||
| // Token = tokenS | |||||
| // }); | |||||
| await identityService.SaveTrackAsync(new GrpcShared.DTO.Db.SaveTrackRequest | await identityService.SaveTrackAsync(new GrpcShared.DTO.Db.SaveTrackRequest | ||||
| { | { | ||||
| Title = track.Item.Name, | Title = track.Item.Name, | ||||
| Album = track.Item.Album.Name, | Album = track.Item.Album.Name, | ||||
| Artist = track.Item.Artists[0].Name, | Artist = track.Item.Artists[0].Name, | ||||
| UserId = "630748c8d149033aaf5a774a" | |||||
| UserId = userId | |||||
| }); | }); | ||||
| //var resp = await identityService.ListUsersAsync(new VoidMessage()); | //var resp = await identityService.ListUsersAsync(new VoidMessage()); | ||||
| //var tokenFromDb = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage | |||||
| // { | |||||
| // Id = "63074188426efd486fadd74d" | |||||
| // }); | |||||
| var tokenFromDb = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage | |||||
| { | |||||
| Id = userId | |||||
| }); | |||||
| //var trackByUser = await identityService.GetTrackByUserAsync(new GrpcShared.DTO.Db.DbRequestMessage | |||||
| // { | |||||
| // Id = "63074188426efd486fadd74d" | |||||
| // }); | |||||
| var trackByUser = await identityService.GetTrackByUserAsync(new GrpcShared.DTO.Db.DbRequestMessage | |||||
| { | |||||
| Id = userId | |||||
| }); | |||||
| //await identityService.DeleteTrackAsync(new GrpcShared.DTO.Db.DbRequestMessage | //await identityService.DeleteTrackAsync(new GrpcShared.DTO.Db.DbRequestMessage | ||||
| // { | // { | ||||
| // Id = "630743c91631901f903f9254" | |||||
| // }); | |||||
| // await identityService.SaveTrackAsync(new GrpcShared.DTO.Db.SaveTrackRequest | |||||
| // { | |||||
| // TrackId = track.Item.Id, | |||||
| // Title = track.Item.Name, | |||||
| // Album = track.Item.Album.Name, | |||||
| // Artist = track.Item.Artists[0].Name, | |||||
| // UserId = "63074188426efd486fadd74d" | |||||
| // Id = | |||||
| // }); | // }); | ||||
| //find id from local storage | |||||
| await identityService.DeleteUserAsync(new GrpcShared.DTO.Db.DbRequestMessage | |||||
| await identityService.SaveTrackAsync(new GrpcShared.DTO.Db.SaveTrackRequest | |||||
| { | { | ||||
| Id = "630748c8d149033aaf5a774a" | |||||
| TrackId = track.Item.Id, | |||||
| Title = track.Item.Name, | |||||
| Album = track.Item.Album.Name, | |||||
| Artist = track.Item.Artists[0].Name, | |||||
| UserId = userId | |||||
| }); | }); | ||||
| //find id from local storage | |||||
| //await identityService.DeleteUserAsync(new GrpcShared.DTO.Db.DbRequestMessage | |||||
| // { | |||||
| // Id = userId | |||||
| // }); | |||||
| } | } | ||||
| } | } |
| @inject IAuthClientService AuthService | @inject IAuthClientService AuthService | ||||
| @inject ITrackClientService SearchService | @inject ITrackClientService SearchService | ||||
| @using System.Security.Claims | @using System.Security.Claims | ||||
| @inject Blazored.LocalStorage.ILocalStorageService localStorage | |||||
| @code { | @code { | ||||
| private string? message; | private string? message; | ||||
| protected override async Task OnInitializedAsync() | |||||
| { | |||||
| var userId = await localStorage.GetItemAsync<string>("user_info"); | |||||
| if (userId != null) NavigationManager.NavigateTo("/home"); | |||||
| } | |||||
| private async Task LoginUser() | private async Task LoginUser() | ||||
| { | { | ||||
| //var response = await SearchService.GetListSearchAsync(new GrpcShared.DTO.Search.SearchRequest() { Query="venom", Type = "track"}); | //var response = await SearchService.GetListSearchAsync(new GrpcShared.DTO.Search.SearchRequest() { Query="venom", Type = "track"}); |
| { | { | ||||
| return await _serviceClient.SaveUserAsync(user); | return await _serviceClient.SaveUserAsync(user); | ||||
| } | } | ||||
| public async Task<VoidMessage> UpdateTokenAsync(UserResponse user) | |||||
| { | |||||
| return await _serviceClient.UpdateTokenAsync(user); | |||||
| } | |||||
| } | } | ||||
| } | } |
| Task<VoidMessage> DeleteTrackAsync(DbRequestMessage id); | Task<VoidMessage> DeleteTrackAsync(DbRequestMessage id); | ||||
| Task<VoidMessage> SaveUserAsync(UserResponse user); | Task<VoidMessage> SaveUserAsync(UserResponse user); | ||||
| Task<VoidMessage> DeleteUserAsync(DbRequestMessage user); | Task<VoidMessage> DeleteUserAsync(DbRequestMessage user); | ||||
| Task<VoidMessage> UpdateTokenAsync(UserResponse user); | |||||
| } | } | ||||
| } | } |
| using Blazored.LocalStorage; | using Blazored.LocalStorage; | ||||
| using GrpcShared.DTO; | using GrpcShared.DTO; | ||||
| using GrpcShared.DTO.Db; | |||||
| using NemAnBlazor.Services.Interfaces; | using NemAnBlazor.Services.Interfaces; | ||||
| namespace NemAnBlazor | namespace NemAnBlazor | ||||
| { | { | ||||
| public static class SpotifyHelper | public static class SpotifyHelper | ||||
| { | { | ||||
| public static async Task<string?> TryRefreshToken(IAuthClientService authService, TokenMessage msg, ILocalStorageService localStorage) | |||||
| public static async Task<string?> TryRefreshToken | |||||
| (IAuthClientService authService, | |||||
| TokenMessage msg,UserResponse user, | |||||
| ILocalStorageService localStorage, | |||||
| IIdentityClientService identityService) | |||||
| { | { | ||||
| var refreshResponse = await authService.RefreshAccessToken(msg); | var refreshResponse = await authService.RefreshAccessToken(msg); | ||||
| if (refreshResponse.AccessToken != null) | if (refreshResponse.AccessToken != null) | ||||
| { | { | ||||
| await localStorage.SetItemAsync<string>("token", refreshResponse.AccessToken); | |||||
| await identityService.UpdateTokenAsync(new UserResponse | |||||
| { | |||||
| Id = user.Id, | |||||
| Token = refreshResponse.AccessToken, | |||||
| RefreshToken = user.RefreshToken | |||||
| }); | |||||
| return refreshResponse.AccessToken; | return refreshResponse.AccessToken; | ||||
| } | } | ||||
| else return null; | else return null; |
| <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> | <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> | ||||
| <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | <PackageReference Include="protobuf-net.Grpc" Version="1.0.171" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | |||||
| <ProjectReference Include="..\gRPCServer\SpotifyService.csproj" /> | |||||
| <ProjectReference Include="..\IdentityProvider\IdentityProvider.csproj" /> | |||||
| </ItemGroup> | |||||
| </Project> | </Project> |
| public class Worker : BackgroundService | public class Worker : BackgroundService | ||||
| { | { | ||||
| private readonly ILogger<Worker> _logger; | private readonly ILogger<Worker> _logger; | ||||
| private HttpClient _httpClient; | |||||
| public Worker(ILogger<Worker> logger) | public Worker(ILogger<Worker> logger) | ||||
| { | { | ||||
| _logger = logger; | _logger = logger; | ||||
| } | } | ||||
| public override Task StartAsync(CancellationToken cancellationToken) | |||||
| { | |||||
| _httpClient = new HttpClient(); | |||||
| return base.StartAsync(cancellationToken); | |||||
| } | |||||
| protected override async Task ExecuteAsync(CancellationToken stoppingToken) | protected override async Task ExecuteAsync(CancellationToken stoppingToken) | ||||
| { | { | ||||
| while (!stoppingToken.IsCancellationRequested) | while (!stoppingToken.IsCancellationRequested) | ||||
| { | { | ||||
| _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); | _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); | ||||
| await Task.Delay(1000, stoppingToken); | |||||
| await Task.Delay(5000, stoppingToken); | |||||
| } | } | ||||
| } | } | ||||
| } | } |