Я обновил приложение функции Azure с .NET 6 in-process
до .NET 8 isolated
. Я использую Azure SignalR в бессерверном режиме. Экземпляр SignalR работает в Azure. Мое приложение работает локально и пытается договориться с экземпляром SignalR в Azure. У меня есть клиент Angular, который вызывает мое приложение-функцию, чтобы установить соединение WebSocket с SignalR. До обновления все работало отлично.
После обновления мой клиент не может подключиться к SignalR, выдавая следующую ошибку:
Ошибка: Не удалось запустить соединение: Ошибка: Ни один транспорт поддерживаются клиентом, поддерживаются сервером.
Ответ, который клиент получает от приложения-функции, такой же, как и до обновления. URL-адрес тот же и содержит AccessToken.
{
"Url": "https://{name}.service.signalr.net/client/?hub=MyHub",
"AccessToken": // token
}
Мой вопрос: почему это происходит? Ни клиент, ни сервер SignalR не изменились. Если я запускаю приложение локально в .NET 6, оно работает, но в .NET 8 сообщает, что сервер не поддерживает тип транспорта. URL-адрес, возвращенный в результате переговоров, тот же, отличается только токен (очевидно). Что происходит?
[FunctionName("negotiate")]
public async Task<SignalRConnectionInfo> Negotiate(
[HttpTrigger(AuthorizationLevel.Anonymous, Route = "MyRoute")] HttpRequest req,
[SignalR(HubName = FunctionsConstants.SignalRAlarmNotificationsHub)] IAsyncCollector<SignalRGroupAction> signalRGroupActions,
IBinder binder)
{
Guid userId = // get UserId from database
await signalRGroupActions.AddAsync(
new SignalRGroupAction {
UserId = userId.ToString(),
GroupName = "MyGroup",
Action = GroupAction.Add
});
return binder.Bind<SignalRConnectionInfo>(
new SignalRConnectionInfoAttribute {
HubName = "MyHub",
UserId = userId.ToString()
});
}
В изолированном режиме WebJobs
недоступен. Вместо этого я использую Worker
.
[Function("negotiate")]
public async Task<SignalRConnectionInfo> Negotiate([HttpTrigger(AuthorizationLevel.Anonymous, Route = "MyRoute")] HttpRequestData req)
{
Guid userId = // get UserId from database
await SignalRDao.AddUserToGroup(userId, "MyGroup");
NegotiationResponse negotiationResponse = await signalRDao.NegotiateForUser(userId);
return new SignalRConnectionInfo {
AccessToken = negotiationResponse.AccessToken,
Url = negotiationResponse.Url
};
}
public class SignalRDao(IConfiguration configuration) : IHostedService
{
private ServiceHubContext _serviceHubContext;
public async Task AddUserToGroup(Guid userId, string groupName)
{
await _serviceHubContext.Groups.AddToGroupAsync(userId.ToString(), groupName);
}
public async Task<NegotiationResponse> NegotiateForUser(Guid userId)
{
return await _serviceHubContext.NegotiateAsync(new NegotiationOptions { UserId = userId.ToString() });
}
public async Task SendSignalRNotification(string message, string groupName)
{
await _serviceHubContext.Clients.Group(groupName).SendCoreAsync("HubName", [message]));
}
#region IHostService Functions
async Task IHostedService.StartAsync(CancellationToken cancellationToken)
{
using ServiceManager serviceManager = new ServiceManagerBuilder()
.WithOptions(o => o.ConnectionString = configuration[ConfigurationConstants.AzureSignalRConnectionString])
.BuildServiceManager();
_serviceHubContext = await serviceManager.CreateHubContextAsync("HubName", cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await _serviceHubContext.DisposeAsync();
}
#endregion
}
services.AddSingleton<ISignalRDao, SignalRDao>();
services.AddHostedService(serviceProvider => serviceProvider.GetRequiredService<ISignalRDao>());
Функция SendSignalRNotification
из SignalRDao
работает после обновления. Он отправляет сообщения в службу SignalR, работающую в Azure.
Спасибо!
@jdweng Я обновил службу SignalR до последней версии, но эта проблема все еще возникает
Есть ли вариант «в процессе» с .net 8 в Azure? В настоящее время я сталкиваюсь с аналогичной проблемой, когда у signalr не работают веб-сокеты при развертывании в среде, отличной от Azure. Я обнаружил, что веб-сокеты могут не работать за пределами внутрипроцессного хостинга.
См. ссылку в этом абзаце: Learn.microsoft.com/en-us/aspnet/signalr/overview/…
@jdweng, но клиент поддерживает типы транспорта, как и сервер. Потому что в .NET 6 всё работает.
Вы пробовали прочитать ссылку, которую я дал? У Transport and Fallback есть множество решений вашей проблемы.
Свойства ответа начинаются с заглавной буквы. Это вызывает разные ошибки в разных клиентах SignalR.
Чтобы этого не произошло, измените ответ:
AccessToken
до accessToken
Url
до url
Я думаю, что версия SinnalR несовместима с Net 8. Возможно, вам придется выполнить чистую сборку.