aspnetcore: [SignalR] Initial ping is not guarded with connection lock
Description
It usually (but not always) throws when flushing buffer segments to send a SignalR hub invocation message over named pipe client stream.
- Managed Test: wegylexy/SignalRTunnel/…/src/Test/Test.cs#L145
- NativeAOT Test: wegylexy/SignalRTunnel/…/src/Native/Connection.cs#L145
Coincidentally, they are both line 145 in my code.
Usually:
Message:
System.ArgumentNullException : Value cannot be null. (Parameter 'array')
Stack Trace:
TlsOverPerCoreLockedStacksArrayPool`1.Return(T[] array, Boolean clearArray)
BufferSegment.ResetMemory()
StreamPipeWriter.FlushAsyncInternal(Boolean writeToStream, ReadOnlyMemory`1 data, CancellationToken cancellationToken)
HubConnection.SendHubMessage(ConnectionState connectionState, HubMessage hubMessage, CancellationToken cancellationToken)
HubConnection.InvokeCore(ConnectionState connectionState, String methodName, InvocationRequest irq, Object[] args, String[] streams, CancellationToken cancellationToken)
HubConnection.InvokeCoreAsyncCore(String methodName, Type returnType, Object[] args, CancellationToken cancellationToken)
ForceAsyncAwaiter`1.GetResult()
HubConnection.InvokeCoreAsync(String methodName, Type returnType, Object[] args, CancellationToken cancellationToken)
...
Rarely:
Message:
System.NullReferenceException : Object reference not set to an instance of an object.
Stack Trace:
StreamPipeWriter.FlushAsyncInternal(Boolean writeToStream, ReadOnlyMemory`1 data, CancellationToken cancellationToken)
HubConnection.SendHubMessage(ConnectionState connectionState, HubMessage hubMessage, CancellationToken cancellationToken)
HubConnection.InvokeCore(ConnectionState connectionState, String methodName, InvocationRequest irq, Object[] args, String[] streams, CancellationToken cancellationToken)
HubConnection.InvokeCoreAsyncCore(String methodName, Type returnType, Object[] args, CancellationToken cancellationToken)
ForceAsyncAwaiter`1.GetResult()
HubConnection.InvokeCoreAsync(String methodName, Type returnType, Object[] args, CancellationToken cancellationToken)
...
Stack reference sources
- dotnet/runtime/…/TlsOverPerCoreLockedStacksArrayPool.cs#L130
- dotnet/runtime/…/BufferSegment.cs#L73
- dotnet/runtime/…/StreamPipeWriter.cs#L313
- dotnet/aspnetcore/…/HubConnection.cs#L868
Configuration
.NET 6 RC1 on Windows 10 (21390) x64, no matter managed or NativeAOT
Regression?
Other information
Server can invoke methods on client via named pipe. It is just client that usually breaks.
Managed and native versions serialize hub invocation arguments differently. Managed version uses official package. Native version uses custom C++ code. Nonetheless, they get written to the buffer successfully, until flushing breaks it.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 24 (24 by maintainers)
Commits related to this issue
- [release/6.0-rc2] Fixes #37340 Fixes #37340 — committed to wegylexy/AspNetCore by wegylexy 3 years ago
- Update to .NET 6.0 RC2; Workaround https://github.com/dotnet/aspnetcore/issues/37340 for native — committed to wegylexy/SignalRTunnel by wegylexy 3 years ago
- Fix #37340; Work around mock testing error — committed to wegylexy/AspNetCore by wegylexy 3 years ago
- Fix #37340 by guarding the initial ping for SignalR (#37414) — committed to dotnet/aspnetcore by wegylexy 3 years ago
- Cherry-pick #37414 to [release/6.0] for #37340 (#37417) — committed to dotnet/aspnetcore by wegylexy 3 years ago
It seems like it’s related to the usage of the StreamPipeWriter in the HubConnection. I think we can move this issue to ASP.NET