我有一个websocket服务器应用程序,我最近从。net Core 2.1升级到3.1,然而,从那时起,协商似乎失败了。这是我的控制台显示的错误。
我尽我最大的努力去遵循所有关于如何最好地升级到3.1的微软文档。在下面的代码中,您可以找到我的c#服务器当前使用的所有包。我知道3.1你不需要参考SignalR包,因为Microsoft.AspNetCore.App已经足够了,但是我在别人的帖子上看到它帮助了他们,所以我试图把它添加到我的(没有运气)。
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.24" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.0.2105168" />
<PackageReference Include="RabbitMQ.Client" Version="5.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.10" />
</ItemGroup>
这是我的Startup类的代码:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ConnectionOptions>(Configuration.GetSection("MQConfig"));
services.AddHostedService<LiveUpdaterService>();
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowAnyOrigin()
.AllowCredentials();
});
});
//I also tried services.AddSignalR();
services.AddSignalRCore();
services.AddMvc(options => options.EnableEndpointRouting = false)
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//app.UseHsts();
}
app.UseCors(cors =>
{
cors.AllowAnyHeader();
cors.AllowAnyOrigin();
cors.AllowAnyMethod();
cors.AllowCredentials();
});
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<LiveUpdateHub>("/liveupdatehub", options =>
{
options.Transports =
HttpTransportType.WebSockets |
HttpTransportType.LongPolling;
});
endpoints.MapControllers();
});
app.UseMvc();
}
}
这是我的JavaScript客户端的代码:
import { HubConnectionBuilder, LogLevel } from "@microsoft/signalr";
var connection;
var connected;
export default class LiveDataHub {
connectWebSocket() {
connection = new HubConnectionBuilder()
.withUrl("http://localhost:5003/liveupdatehub")
.configureLogging(LogLevel.Information)
.withAutomaticReconnect()
.build();
//Disable button until connection is established
document.getElementById("runTestButton").disabled = true;
connection.onclose(function (error) {
document.getElementById("runTestButton").disabled = true;
connected = false;
console.log(error)
alert("There was a problem connecting to the backend, please try again");
});
connection
.start()
.then(function () {
document.getElementById("runTestButton").disabled = false;
console.log(connection);
connected = true;
})
.catch(function (err) {
alert("No connection could be made to the backend, please refresh: " + err.toString());
connected = false;
return console.error(err.toString());
});
return connection;
}
到目前为止,对于服务器,我已经尝试移动Configure和ConfigureServices方法,因为我知道它们的顺序在3.1中很重要,但也许有一个位置我错过了。我还尝试添加了很多额外的配置方法,我从其他帖子中读到,比如(options =>选项。EnableEndpointRouting = false)或AddNewtonSoftJson().
对于客户端,我试图通过添加以下内容来跳过协商部分:
connectWebSocket() {
connection = new HubConnectionBuilder()
.withUrl("ws://localhost:5003/liveupdatehub", {
skipNegotiation: true,
transport: HttpTransportType.WebSockets
})
.configureLogging(LogLevel.Information)
.withAutomaticReconnect()
.build();
但是控制台错误日志会变成这样。这就是为什么我认为SignalR是主要问题。
如果有人能帮我解决这个问题,我将非常感激!所以一段时间后我发现了潜在的问题是什么。结果是,调用services.AddHostedService()会导致托管服务在SignalR连接建立之前被调用,并且因为我的LiveUpdaterService依赖于SignalR,它会导致整个连接崩溃。
注释该方法后,协商与我的应用程序的其余部分一起工作(除了LiveUpdaterService)。如果有人感兴趣的话,我通过这个链接找到了答案:https://github.com/Azure/azure-signalr/issues/909。我目前正试图找到一个解决这个问题的解决方案,但至少现在连接正在工作。
我将此标记为已解决,因为addhostdservice更多的是一个兼容性问题。希望这能帮助到有同样问题的人。
我的Startup的最终代码:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSignalR();
services.Configure<ConnectionOptions>(Configuration.GetSection("MQConfig"));
services.AddCors(options =>
{
options.AddPolicy("AllowSetOrigins",
builder =>
{
builder
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.WithOrigins("http://localhost:5003")
.WithOrigins("http://localhost:8080");
});
});
//services.AddHostedService<LiveUpdaterService>();
}
// 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();
}
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();
app.UseRouting();
app.UseCors("AllowSetOrigins");
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHub<LiveUpdateHub>("/liveupdatehub");
});
}
}
包的最终代码:
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="RabbitMQ.Client" Version="5.2.0" />
</ItemGroup>