Вопрос в предложении: остаются ли соединения SignalR открытыми через keep-alive, если да, то почему они не работают в .NET Core 3, и если нет, то для чего нужны настройки keep-alive?
У меня есть веб-приложение ASP.NET Core 3.0 MVC, и я просто добавил в него SignalR, следуя инструкции по началу работы, расположенной здесь: https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-3.0&tabs=visual-studio (за исключением создания нового веб-приложения, мы просто добавили его в нашевместо приложения)
У меня есть простой концентратор, и клиент успешно подключается, и если я проверяю метод SignalR сразу после установления соединения, он работает. Тем не менее, соединение закрывается, если я не использую его в течение 30 секунд. Если я понимаю документацию, значение keepalive по умолчанию составляет 15 секунд, но я не вижу сообщений keepalive. Я пробовал различные настройки для KeepAliveInterval и ClientTimeoutInterval, но ничего не решило это.
Я добавил .withAutomaticReconnect () к вызову HubConnectionBuilder в нашем javascript, и это работает для восстановления соединения после отключения каждый раз30 секунд. Это то, как это должно работать, или соединение должно поддерживаться эхо-запросами и должно быть переподключено только из-за пропадания сети и т. Д.? Я чувствую, что упускаю что-то простое или неправильно понимаю, как это должно работать.
Вот различные части нашего кода:
Startup.cs Метод ConfigureServices:
services.AddSignalR(hubOptions =>
{
hubOptions.EnableDetailedErrors = true;
//hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(10);
//hubOptions.ClientTimeoutInterval = TimeSpan.FromMinutes(1);
});
Startup.cs Настроить метод:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
endpoints.MapHub<QuoteHub>("/quoteHub");
});
Наш QuoteHub:
public class QuoteHub : Hub
{
public QuoteHub()
{
}
public override Task OnConnectedAsync()
{
var quoteId = Context.GetHttpContext().Request.Query["quoteId"];
return Groups.AddToGroupAsync(Context.ConnectionId, quoteId);
}
}
и настройка соединения javascript:
const setupQuoteConnection = (quoteId) => {
let connection = new signalR.HubConnectionBuilder()
.withUrl("/quoteHub?quoteId=" + quoteId)
.configureLogging(signalR.LogLevel.Debug)
.withAutomaticReconnect()
.build();
connection.on("ReceiveUpdate", (update) => {
alert(update);
}
);
connection.start()
.catch(err => console.error(err.toString()));
};
и, если быть точным, вызов концентратору для отправки обновления клиентам:
_quoteHub.Clients.Group(domainEvent.QuoteId.ToString()).SendAsync("ReceiveUpdate", domainEvent.TotalPrice);
Обновление
Я нашел образец чата, расположенный по адресу https://github.com/aspnet/SignalR-samples. Я скачал и запустил этот образец, и он отлично работает, соединение остается открытым, но на всю жизньЯ не могу понять, что заставляет его работать иначе, чем мое приложение.
Я заметил некоторые проблемы в моем концентраторе и исправил их, хотя это не имело никакого значения:
public class QuoteHub : Hub
{
public override async Task OnConnectedAsync()
{
var quoteId = Context.GetHttpContext().Request.Query["quoteId"];
await Groups.AddToGroupAsync(Context.ConnectionId, quoteId);
await base.OnConnectedAsync();
}
}
ТогдаЯ обновил свой код JavaScript, чтобы настроить соединение и увеличить время ожидания сервера. Это действительно работает , но зачем мне это нужно, если в приведенном выше примере связанного чата его нет и прекрасно работает без него?
let connection = new signalR.HubConnectionBuilder()
.withUrl("/quoteHub?quoteId=" + quoteId)
.configureLogging(signalR.LogLevel.Debug)
.withAutomaticReconnect()
.build();
connection.serverTimeoutInMilliseconds = 3600000; //1 hour