У меня есть набор приложений, которые взаимодействуют с сервером gRP C. Эти приложения работают на стороне сервера Blazor, и все работает хорошо, почти !!! Это должно работать почти как локальный чат. Я пишу одну вещь на одной машине, и все другие машины получают это и показывают это. Чтобы показать это, у меня есть таймер, проверяющий, получено ли что-нибудь приложением собственной службы gRP C, я перетаскиваю эти данные в переменные страницы и состояние вызова изменилось. Проблема в том, что страница зависает через некоторое время. И это происходит всегда, когда над ними никто не работает. И я не получаю никакой ошибки. Может кто-нибудь, пожалуйста, помогите мне ?????????? *
Код на странице:
@code {
bool registred = false;
int countLogingAttempts = 2;
string Name = "first name";
public string displayLoader = "block";
public string displayQueuesContainer = "none";
private string Time { get; set; }
public System.Threading.Timer LoginTimer { get; set; }
public string[] queueNames = new string[0];
public int[] queueNumbers = new int[0];
public int countStateChanged = 0;
string selectedQueueName = "";
string SelectedQueueName
{
get => selectedQueueName;
set
{
selectedQueueName = value;
}
}
public bool[] displayQueues = new bool[4] { false, false, false, false };
protected override void OnInitialized()
{
jsRuntime.InvokeAsync<string>("console.log", "intilializing " + countLogingAttempts);
LoginTimer = new System.Threading.Timer((_) =>
{
jsRuntime.InvokeAsync<string>("console.log", "Tiking");
if (!registred)
{
int capturedint = countLogingAttempts;
jsRuntime.InvokeAsync<string>("console.log", "Trying " + capturedint);
if (countLogingAttempts == 5)
{
Task.Run(() => SayHello());
countLogingAttempts = 0;
jsRuntime.InvokeAsync<string>("console.log", "Say hello ");
}
countLogingAttempts += 1;
}
else
{
displayLoader = "none";
displayQueuesContainer = "block";
InvokeAsync(StateHasChanged);
updatePage();
jsRuntime.InvokeAsync<string>("console.log", "Disposed" + countLogingAttempts);
LoginTimer.Dispose();
}
}, null, 0, 1000);
}
public void updatePage()
{
var timer = new System.Threading.Timer((_) =>
{
if (registred)
{
Time = DateTime.Now.ToString("HH:mm");
jsRuntime.InvokeAsync<string>("console.log", "Registred." + countLogingAttempts);
queueNames = GreeterService1.queueNames;
queueNumbers = GreeterService1.queueNumbers;
InvokeAsync(StateHasChanged);
}
}, null, 0, 1000);
}
async Task SayHello()
{
this.registred = await this.GreeterService1.SayHello(this.Name);
await jsRuntime.InvokeAsync<string>("console.log", "waiting for hello " + registred);
}
Некоторая разметка:
<div class="col col-sm-auto col-clock">
<div style="margin-right:0px;width: 125px;">
<h5 id="clock">@Time</h5>
</div>
</div>
<div class="container-fluid main-container">
<div class="row main-row">
<div id="queueContainer" class="col col-md-auto senhas-col">
@if (queueNames!=null) {
if (queueNames.Length>0) {
<div class="row senhas-row">
<div class="queue-name-div">
<a class="queue-name-a ">@queueNames[0]</a>
The gRP C служба:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.Extensions.Logging;
using GrpcConsole;
using BlazorViewer;
using BlazorViewer.Data;
namespace GrpcService1
{
public class GreeterService : QueueManagement.QueueManagementBase
{
public static string clientName="Initial name";
public string[] queueNames;
public int[] queueNumbers;
public static string calledQueue { get; set; }
public static string publicAuthToken = "token";
public static bool serviceStatus = false;
public static string token = "token";
public static string guidId = "viewer1";
public static string kind = "viewer";
public static int numberInKind = 1;
public static string serverIp = "192.168.5.56";
public async Task<bool> SayHello(string name)
{
bool awnser = false;
Task t = Task.Run(async () => {
var httpClientHandler = new HttpClientHandler();
// Return `true` to allow certificates that are untrusted/invalid
httpClientHandler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(httpClientHandler);
var channel = GrpcChannel.ForAddress("https://"+serverIp+":5001"
, new GrpcChannelOptions { HttpClient = httpClient });
var client = new QueueManagement.QueueManagementClient(channel);
IdMessage message = new IdMessage { Token = token, GuidId = guidId, Kind = kind, NumberInKind = numberInKind };
var request = await client.GeneralRegistryRequestAsync(new RegistryRequest { Identification = message });
awnser = request.RequestAccepted;
});
t.Wait();
Console.WriteLine("Registry made = "+ awnser);
return await Task.FromResult(awnser);
}
public static void ProcessServiceStatus(bool status)
{
serviceStatus = status ? true : false;
}
public override async Task<RequestResponse> UpdateToViewer(ViewerUpdate request, ServerCallContext context)
{
RequestResponse resp = new RequestResponse { RequestAccepted = false };
if (request.Token == publicAuthToken)
{
resp.RequestAccepted = true;
ProcessServiceStatus(request.ServiceStatus);
string[] queueNames1 = request.QueueNames.ToArray();
int[] queueNumbers1 = request.QueueNumbers.ToArray();
queueNames = new string[queueNames1.Length];
queueNumbers = new int[queueNames1.Length];
queueNames = queueNames1;
queueNumbers = queueNumbers1;
Console.WriteLine("Received queues:");
foreach (var item in queueNames)
{
Console.WriteLine(item);
}
}
return await Task.FromResult(resp);
}
}
}
Файл запуска:
namespace BlazorViewer
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<GreeterService>();
services.AddGrpc();
services.AddServerSideBlazor().AddCircuitOptions(options => { options.DetailedErrors = true; });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
}