Kestrel WebSocket AcceptWebSocketAsync NRE
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Describe the bug
Hi!
I’m building library which encapsulates web-server for WebSocket connection using Kestrel
(let’s name it A)
/* simple version of my code */
var hostBuilder = new WebHostBuilder()
.UseKestrel()
.UseUrls("http://127.0.0.1:8008/");
hostBuilder.Configure(app =>
{
app.UseWebSockets();
app.Run(async context =>
{
if (context.WebSockets.IsWebSocketRequest)
{
await context.WebSockets.AcceptWebSocketAsync(); // throws NRE at ConnectAsync request
Console.WriteLine("Connected");
}
});
});
var host = hostBuilder.Build();
host.Start();
In my specific case: dinamic link library A is loaded in my project in runtime using
Assembly.LoadFrom(assemblyPath);
...
Activator.CreateInstance(...);
Which means I need all dependent dlls in output folder where my main application starts, so all dependecies could be resolved in runtime.
Problem with websockets was already discussed here
- https://github.com/dotnet/aspnetcore/issues/28112
- https://github.com/dotnet/aspnetcore/issues/29884
- https://github.com/dotnet/aspnetcore/issues/41416
According to https://github.com/dotnet/aspnetcore/issues/28112#issuecomment-733635589 the problem only appears if Microsoft.Extensions.Configuration
greater than 2.2.0 is used.
In my specific case:
dependencies from other projects use Microsoft.Extensions.Configuration
5.0.0 so I can’t use 2.2.0
I tried solution mentioned here https://github.com/dotnet/aspnetcore/issues/28112#issuecomment-733662430 :
<ItemGroup>
+ <FrameworkReference Include="Microsoft.AspNetCore.App" />
- <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
</ItemGroup>
but for project with
<OutputType>Library</OutputType>
FrameworkReferenced dlls aren’t copied in output folder 😞 even with flags (but referenced nuget packages are copied)
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
So if I use
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
I got
Could not load file or assembly 'Microsoft.AspNetCore.Hosting.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
But if I manually copy all runtime dlls from folder: C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.4
to output folder, everything works fine.
Reading comments from other issues and migration guide, I’m still not sure what to do in my case and how to make it work 😢
I mean, I don’t understand is there problem with my approach? Will the problem with Microsoft.Extensions.Configuration
be fixed or I should change my approach?
Is there any workaround for my problem, at the moment?
Same mechanism with HttpSys
works fine.
Thank you in advance!
Expected Behavior
WebSocket connection accepted without NRE.
Steps To Reproduce
Reproduction of problem with websockets - https://github.com/mishhan/kestrel-websocket-bug-repro Simple reproduction of my specific case - https://github.com/mishhan/kestrel-webscocket-activator-bug-repro
Exceptions (if any)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.CreateResponseHeader(Boolean appCompleted) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProduceStart(Boolean appCompleted) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.InitializeResponseAsync(Int32 firstWriteByteCount) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.FlushAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature.UpgradeAsync() at Microsoft.AspNetCore.WebSockets.WebSocketMiddleware.UpgradeHandshake.AcceptAsync(WebSocketAcceptContext acceptContext) at Program.<>c.<<<Main>$>b__0_1>d.MoveNext() at C:\Users\misha\source\repos\KestrelWebSocket\KestrelWebSocket\Program.cs:строка 22
.NET Version
6.0.200
Anything else?
No response
Issue Analytics
- State:
- Created a year ago
- Comments:6 (4 by maintainers)
https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-6.0&tabs=visual-studio#migrate-libraries-via-multi-targeting
Think of it like this, when you’re trying to use things that depend on ASP.NET Core, you need to have ASP.NET Core there already. Either the host brings in ASP.NET Core, or the plugin does. To get the plugin to deploy the shared framework, then you need to get self contain deploy the shared framework. That means each plugin will bring the whole thing, you don’t want that. The host should represent the shared footprint that most plugins need to run. In this case, a plugin should be able to depend on ASP.NET Core without brining it and the host should provide it if required by the plugin.
Just remove those package dependencies and use a framework reference. Your host application should also have that same framework reference and it will work like magic 😄