SignalR 立即断开连接,.NET Core 3.1 上没有代码更改
SignalR Disconnects Immediately with no code changes on .NET Core 3.1
我正准备拔头发。在我上次提交后,下面的代码运行完美。我进行了一系列重要的代码更改和重构,并且在该过程中的某个地方 SignalR 停止正常工作。在多次调试失败后,我将整个代码库恢复到最后一次工作提交,而 SignalR 仍然无法工作。
当我加载页面时,应用程序启动并启动 SignalR 连接。协商成功,与集线器的连接也成功,但立即断开连接。以下是断开连接前仅有的两条消息:
没有控制台长,但是当我单步执行客户端 websockets 代码时,我发现连接以 code=1000
和 reason=''
终止。我比较有信心连接被服务器终止,但无法确定。我的应用程序使用 TLS,所以我无法通过数据包嗅探来查看实际情况。
这是我尝试过的:
使服务器和客户端超时时间更长。
在客户端和服务器上设置一个非常短的 Keepalive 间隔。
尝试过 Edge、Firfox,并从另一台计算机连接。
删除所有二进制文件并重新启动 Visual Studio。
IISExpress、IIS 和普通应用程序。
Updated/reinstalled 所有 nuget 包。
这是我的 Startup.cs:
的相关内容
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR(options =>
{
options.KeepAliveInterval = TimeSpan.Zero;
});
services.AddControllersWithViews();
services.AddRazorPages();
services.ConfigureCoreServices();
services.ConfigureLiquidMeterServices();
}
// 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();
app.UseBrowserLink();
}
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(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "ClientApp/dist")),
RequestPath = "/static"
});
var webSocketOptions = new WebSocketOptions()
{
KeepAliveInterval = TimeSpan.Zero,
};
app.UseWebSockets(webSocketOptions);
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapHub<LiquidMeterHub>("/lmhub");
endpoints.MapRazorPages();
});
}
我的中心代码最少,非常样板。
这是我的前端打字稿代码:
class SomeSignalRService{
connection?: signalR.HubConnection;
...
initialize(){
this.connection = new signalR.HubConnectionBuilder()
.withUrl("/lmHub")
.configureLogging(signalR.LogLevel.Information)
.build();
this.connection.on("clientUpdate", this.clientUpdate.bind(this));
this.connection.onclose(this.onClose.bind(this));
this.connection.start()
.then(() => {
//dispatch connected event;
});
}
我弄明白了,SignalR 和 Websocket 接口中有一个异常不会显示在输出中,除非安装了以下日志过滤器:
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
})
错误是由序列化程序无法解析 double.NaN
引起的。考虑到 NaN
是一个有效的 json 值,这有点奇怪。我添加了检查以将 NaN
的任何双精度值设置为 0
。
我正准备拔头发。在我上次提交后,下面的代码运行完美。我进行了一系列重要的代码更改和重构,并且在该过程中的某个地方 SignalR 停止正常工作。在多次调试失败后,我将整个代码库恢复到最后一次工作提交,而 SignalR 仍然无法工作。
当我加载页面时,应用程序启动并启动 SignalR 连接。协商成功,与集线器的连接也成功,但立即断开连接。以下是断开连接前仅有的两条消息:
没有控制台长,但是当我单步执行客户端 websockets 代码时,我发现连接以 code=1000
和 reason=''
终止。我比较有信心连接被服务器终止,但无法确定。我的应用程序使用 TLS,所以我无法通过数据包嗅探来查看实际情况。
这是我尝试过的: 使服务器和客户端超时时间更长。 在客户端和服务器上设置一个非常短的 Keepalive 间隔。 尝试过 Edge、Firfox,并从另一台计算机连接。 删除所有二进制文件并重新启动 Visual Studio。 IISExpress、IIS 和普通应用程序。 Updated/reinstalled 所有 nuget 包。
这是我的 Startup.cs:
的相关内容public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR(options =>
{
options.KeepAliveInterval = TimeSpan.Zero;
});
services.AddControllersWithViews();
services.AddRazorPages();
services.ConfigureCoreServices();
services.ConfigureLiquidMeterServices();
}
// 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();
app.UseBrowserLink();
}
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(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "ClientApp/dist")),
RequestPath = "/static"
});
var webSocketOptions = new WebSocketOptions()
{
KeepAliveInterval = TimeSpan.Zero,
};
app.UseWebSockets(webSocketOptions);
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapHub<LiquidMeterHub>("/lmhub");
endpoints.MapRazorPages();
});
}
我的中心代码最少,非常样板。 这是我的前端打字稿代码:
class SomeSignalRService{
connection?: signalR.HubConnection;
...
initialize(){
this.connection = new signalR.HubConnectionBuilder()
.withUrl("/lmHub")
.configureLogging(signalR.LogLevel.Information)
.build();
this.connection.on("clientUpdate", this.clientUpdate.bind(this));
this.connection.onclose(this.onClose.bind(this));
this.connection.start()
.then(() => {
//dispatch connected event;
});
}
我弄明白了,SignalR 和 Websocket 接口中有一个异常不会显示在输出中,除非安装了以下日志过滤器:
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
})
错误是由序列化程序无法解析 double.NaN
引起的。考虑到 NaN
是一个有效的 json 值,这有点奇怪。我添加了检查以将 NaN
的任何双精度值设置为 0
。