This commit is contained in:
MeysamMoghaddam
2025-10-12 22:49:09 +03:30
parent 609060e1d5
commit 80e0f4172e
2 changed files with 34 additions and 67 deletions

View File

@@ -33,22 +33,38 @@ public static class ConfigureServices
public static IServiceCollection AddGrpcServices(this IServiceCollection services, IConfiguration configuration)
{
var baseUrl = configuration["GwUrl"];
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
httpClient.Timeout = TimeSpan.FromMinutes(10); // TODO Check Timeout
var serviceProvider = services.BuildServiceProvider();
var channel = CreateAuthenticatedChannel(baseUrl, httpClient, serviceProvider);
services.AddScoped(sp => new PackageContract.PackageContractClient(channel));
services.AddScoped(sp => new UserContract.UserContractClient(channel));
services.AddScoped(sp => new UserAddressContract.UserAddressContractClient(channel));
services.AddScoped(sp => new UserOrderContract.UserOrderContractClient(channel));
// Register optimized HttpClient for gRPC
services.AddScoped(sp =>
{
var handler = new HttpClientHandler
{
MaxConnectionsPerServer = 10,
AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate
};
return new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, handler))
{
Timeout = TimeSpan.FromMinutes(10),
BaseAddress = new Uri(baseUrl)
};
});
// Register gRPC clients with authentication
services.AddScoped(CreateAuthenticatedClient<PackageContract.PackageContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserContract.UserContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserAddressContract.UserAddressContractClient>);
services.AddScoped(CreateAuthenticatedClient<UserOrderContract.UserOrderContractClient>);
return services;
}
private static GrpcChannel CreateAuthenticatedChannel(string address, HttpClient httpClient, IServiceProvider serviceProvider)
private static TClient CreateAuthenticatedClient<TClient>(IServiceProvider sp)
where TClient : class
{
var localStorage = serviceProvider.GetRequiredService<ILocalStorageService>();
var httpClient = sp.GetRequiredService<HttpClient>();
var localStorage = sp.GetRequiredService<ILocalStorageService>();
var baseUrl = httpClient.BaseAddress?.ToString() ?? throw new InvalidOperationException("Base URL not configured");
var credentials = CallCredentials.FromInterceptor(async (context, metadata) =>
{
@@ -60,22 +76,23 @@ public static class ConfigureServices
metadata.Add("Authorization", $"Bearer {token}");
}
}
catch (Exception)
catch (Exception ex)
{
// Ignore errors during token retrieval
#if DEBUG
Console.WriteLine($"Token retrieval error: {ex.Message}");
#endif
}
});
// SslCredentials is used here because this channel is using TLS.
// CallCredentials can't be used with ChannelCredentials.Insecure on non-TLS channels.
var channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions
var channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions
{
UnsafeUseInsecureChannelCallCredentials = true,
Credentials = ChannelCredentials.Create(new SslCredentials(), credentials),
HttpClient = httpClient,
MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB
MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB
MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB
});
return channel;
return (TClient)Activator.CreateInstance(typeof(TClient), channel)!;
}
}

View File

@@ -81,56 +81,6 @@
</div>
</MudTabPanel>
<!-- Password Change Tab -->
<MudTabPanel Text="تغییر رمز عبور" Icon="@Icons.Material.Filled.Lock">
<div class="pa-4">
<MudText Typo="Typo.h6" Class="mb-4 mud-typography-subtitle1">تغییر رمز عبور</MudText>
<MudForm @ref="_passwordForm" Model="_passwordModel" Validation="@((Func<object, IEnumerable<FluentValidation.Results.ValidationFailure>>)((model) => _passwordValidator.Validate((PasswordChangeModel)model).Errors))">
<MudGrid Spacing="3">
<MudItem xs="12">
<MudTextField @bind-Value="_passwordModel.CurrentPassword"
For="@(() => _passwordModel.CurrentPassword)"
Label="رمز عبور فعلی"
Variant="Variant.Outlined"
InputType="InputType.Password"
Required="true"
RequiredError="وارد کردن رمز عبور فعلی الزامی است." />
</MudItem>
<MudItem xs="12" md="6">
<MudTextField @bind-Value="_passwordModel.NewPassword"
For="@(() => _passwordModel.NewPassword)"
Label="رمز عبور جدید"
Variant="Variant.Outlined"
InputType="InputType.Password"
Required="true"
RequiredError="وارد کردن رمز عبور جدید الزامی است." />
</MudItem>
<MudItem xs="12" md="6">
<MudTextField @bind-Value="_passwordModel.ConfirmPassword"
For="@(() => _passwordModel.ConfirmPassword)"
Label="تکرار رمز عبور جدید"
Variant="Variant.Outlined"
InputType="InputType.Password"
Required="true"
RequiredError="تکرار رمز عبور جدید الزامی است." />
</MudItem>
</MudGrid>
<MudStack Row="true" Spacing="2" Justify="Justify.FlexEnd" Class="mt-4">
<MudButton Variant="Variant.Outlined" Color="Color.Secondary" OnClick="CancelPasswordChange">
لغو
</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="ChangePassword" Disabled="_isPasswordChanging">
تغییر رمز عبور
</MudButton>
</MudStack>
</MudForm>
</div>
</MudTabPanel>
<!-- Account Settings Tab -->
<MudTabPanel Text="تنظیمات حساب" Icon="@Icons.Material.Filled.Settings">
<div class="pa-4">