摘要
我正在做一个微服务项目,有几个客户端访问(mvcasp.netweb应用程序,托管的blazor webassembly等)都在kubernetes集群中。最近我将所有应用程序更新到.NET 7,但我不知道这是否是我的问题的原因。
症状
在Blazor Webassembly(Hosted)PWA中,我使用SignalR Hub进行Blazor.Client和Blazor.Server之间的通信。当我调用页面时,然后在页面完全加载之前立即返回,我会得到Web Socket错误。另一方面,应用程序非常慢。
错误
- 未处理异常渲染组件:**无法访问已释放的对象。**对象名称:'集线器连接'.系统.对象处理异常....在集线器连接中.发送核心异步... *
- 未处理异常渲染组件:如果连接未处于活动状态,则无法调用“SendCoreAsync”方法。System.InvalidOperationException....in ReconnectingConnectionState.WaitForActiveConnectionAsync ... *
尝试变通办法
我试图捕捉这些异常,因为我找不到原因或解决方案(扩展方法CallAsync):
if ( hubConnection is not null )
{
try
{
await hubConnection.SendAsync( methodName, arg1, arg2, cancellationToken );
}
catch ( ObjectDisposedException ) { }
catch ( InvalidOperationException ) { }
}
但我还是得到错误消息“操作已取消”。
更多代码
在方法(客户端)中创建集线器连接:
var hubConnection = new HubConnectionBuilder()
.WithUrl( Navigator.ToAbsoluteUri( hubPath ), options =>
{
options.AccessTokenProvider = () => Task.FromResult( ((AuthStateProvider)AuthStateProv).Token );
// added the next lines later to try out
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
options.SkipNegotiation = true;
})
.WithAutomaticReconnect()
.Build();
使用集线器连接(客户端):
// this is the method above passing the hubPath
hubConnection = CreateHubConnection( "/testhub" );
hubConnection.On<MyDataModel>( "ReceiveData", ( result ) => HandleData( result ) );
await hubConnection.StartAsync();
// calling method (first code above)
await CallAsync( hubConnection, "RequestData" );
在剃刀组件中处理轮毂连接:
public override async ValueTask DisposeAsync()
{
if ( hubConnection is not null )
{
try
{
await hubConnection.StopAsync();
}
finally
{
await hubConnection.DisposeAsync();
}
}
}
服务器(Server):
public class TestHub : BaseHub
{
public async Task RequestData()
{
// get data from a microservice api
var result = await _getQuery.Get();
await Clients.Caller.SendAsync( "ReceiveData", result );
}
}
Blazor.服务器启动配置(Program.cs):
builder.Services.AddSignalR( options =>
{
options.ClientTimeoutInterval = TimeSpan.FromSeconds( 60 );
options.HandshakeTimeout = TimeSpan.FromSeconds( 30 );
options.MaximumParallelInvocationsPerClient = 3;
options.EnableDetailedErrors = true;
} );
builder.Services.AddResponseCompression( opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" } );
} );
var app = builder.Build();
app.UseResponseCompression();
app.MapHub<TestHub>( "/testhub" );
首先,我在浏览器中收到此消息:* 警告:Web浏览器不支持关闭WebSocket的输出端。CloseOutputAsync已关闭套接字并丢弃所有传入消息。*
1条答案
按热度按时间krugob8w1#
经过密集的调试,我可以定位异常。
当用户在页面加载时首先返回时,调用了剃刀页面中的DisposeAsync,并且hubConnection被释放但不为null,然后调用OnInitializedAsync,在此创建并启动hubConnection。我还在启动hubConnection后调用了一个方法。因此,在启动hubConnection时抛出了第一个Exception:StartAsync中的OperationCanceledException。调用hub方法时抛出第二个Exception:因此,在这两个位置,我需要添加try/catches,正如jdweng所注意到的那样。
在方法调用中,我已经有了try/catch(参见第一段代码)。我只是在StartAsync中添加了另一个:
btw hubConnection.StopAsync不需要,因为hubConnection.DisposeAsync正在停止hubConnection。HubConnection SendCoreAsyncCore方法首先检查它是否被释放并抛出Exception,在100次调用后,它检查CancellationToken并带有注解“Bail early for cancellation”。