Azure Web App配置SignalR Hub对接Azure SignalR服务的问题求助
问题排查:Azure SignalR Service 连接与组操作异常
问题描述
- Hub无法稳定加载到Azure SignalR Service,报错与Serverless/Default模式相关,日志如下:
2023-02-16T14:05:25.034917571Z info: Microsoft.Azure.SignalR.Connections.Client.Internal.WebSocketsTransport[1] 2023-02-16T14:05:25.034960072Z Starting transport. Transfer mode: Binary. Url: 'wss://nmg-opus-common-inventory-dev-sigr.service.signalr.net/server/?hub=myhub&cid=9e64b380-b752-4175-8fd2-215a2b62139d'. 2023-02-16T14:05:25.057819457Z info: Microsoft.Azure.SignalR.Connections.Client.Internal.WebSocketsTransport[11] 2023-02-16T14:05:25.057859557Z WebSocket closed by the server. Close status NormalClosure. 2023-02-16T14:05:25.057865857Z info: Microsoft.Azure.SignalR.ServiceConnection[24] 2023-02-16T14:05:25.057870457Z Connection to service '(Primary)https://nmg-opus-common-inventory-dev-sigr.service.signalr.net(hub=MyHub)' handshake failed, probably caused by network instability or service restart. Will retry after the back off period. Error detail: Azure SignalR Service is in serverless mode, server connection is not allowed.. Id: 9e64b380-b752-4175-8fd2-215a2b62139d 2023-02-16T14:05:25.057875657Z info: Microsoft.Azure.SignalR.Connections.Client.Internal.WebSocketsTransport[6] 2023-02-16T14:05:25.057880257Z Transport is stopping.
- 将服务设为Serverless模式时,客户端看似连接成功,但调用JoinGroup方法后无响应,连接是在Blazor页面点击元素后建立的。
- 已尝试调整Azure设置、修改代码同步为异步等操作,问题仍未解决。
相关代码
SignalR Hub代码
public class MyHub : Hub { public async Task SendMessage(string groupName, string message) { await Group(groupName).SendAsync("ReceiveMessage", message); } public async Task JoinGroup(string groupName) { await Groups.AddToGroupAsync(Context.ConnectionId, groupName); } public async Task LeaveGroup(string groupName) { await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName); } public override async Task OnConnectedAsync() { await Clients.Client(Context.ConnectionId).SendAsync("Connected", Context.ConnectionId); } }
Web App的Startup代码
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddAzureAppConfiguration(); services.AddSignalR(e => { e.MaximumReceiveMessageSize = 10240000; }); string SignalRURLHub = Configuration.GetValue<string>("Resources:SignalR:Inventory:ConnectionString"); services.AddSignalR().AddAzureSignalR(SignalRURLHub); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAzureAppConfiguration(); app.UseRouting(); var SignalRHubName = $"/{Configuration.GetValue<string>("Resources:SignalR:HubName")}"; app.UseEndpoints(endpoints => { endpoints.MapHub<MyHub>(SignalRHubName); }); } }
客户端连接初始化代码
protected HubConnection _connection; private readonly string groupName; protected ClientHandler(string connectionString, string hubName, string groupName, string userId = null) { var serviceUtils = new ServiceUtils(connectionString); var url = GetClientUrl(serviceUtils.Endpoint, hubName); _connection = new HubConnectionBuilder() .WithUrl(url , option => { option.AccessTokenProvider = () => { return Task.FromResult(serviceUtils.GenerateAccessToken(url, userId)); }; }) .WithAutomaticReconnect(new AlwaysRetryPolicy()) .ConfigureLogging(logging => { logging.SetMinimumLevel(LogLevel.Trace); logging.AddConsole(); }) .Build(); this.groupName = groupName; _connection.Reconnected += JoinGroup; _connection.On("Connected", new[] { typeof(string) }, OnInitialConnection); } private string GetClientUrl(string endpoint, string hubName) { return $"{endpoint}/client/?hub={hubName}"; } private async Task JoinGroup(string contextId) { try { await _connection.InvokeAsync("JoinGroup", groupName); //JoinGroup is C# method name } catch (Exception e) { } } // Called separately after the ClientHandler object is created. public async Task StartAsyncWithRetry(CancellationToken cancellationToken = default) { while (!cancellationToken.IsCancellationRequested) { try { await _connection.StartAsync() .ContinueWith(res => { _connection.InvokeAsync("JoinGroup", groupName); }); if (_connection.State == HubConnectionState.Disconnected) { await Task.Delay(GetRandomDelayMilliseconds()); continue; } return; } catch (Exception e) { await Task.Delay(GetRandomDelayMilliseconds()); } } }
内容的提问来源于stack exchange,提问作者Vinnycout
相关产品推荐
相关产品推荐

