Open ruben-ivre opened 2 months ago
So far I have a workaround it that is to change that WriteAsync function to create an empty invocation message if hubMessage.Message is null, which works for my use case, but it's not a very good solution.
Probably a better option would be to add some info to SerializedHubMessage to be able to reconstruct the proper message type. If you can point me to a proper solution, I can work on that.
Is there an existing issue for this?
Describe the bug
Stateful reconnect requires that both client and server calculate the same sequence Id so when the reconnect happen they can resume on the right message, but when using Redis as backplane a different code path is used, which ends up causing some messages not being accounted for in the server side and creating a discrepancy that leads to lost messages on reconnect. The whole sequence Id calculation happens in MessageBuffer class, which increases the Id every time an invocation message is sent (in WriteAsyncCore), skipping the count otherwise.
The problem is that when using Redis, the message comes as a SerializedHubMessage using a constructor that doesn't set the Message property, so when MessageBuffer tries to determine if it's an invocation message,
is
operator returns false as the message is null, and thus this message doesn't increment the sequence Id. On the client side is read correctly, identified as an Invocation, and increments the sequence Id, create a discrepancy that will essentially break stateful reconnect.Expected Behavior
Sequence Id is kept in sync in both client side and server side. This is critical for stateful reconnect to work properly.
Steps To Reproduce
Exceptions (if any)
No response
.NET Version
8.0.3
Anything else?
The issue is pretty easy to spot once you know where to look.
Observe here how MessageBuffer.cs:124 expects Message property to be not null.![image](https://github.com/dotnet/aspnetcore/assets/68167947/2dc248bd-f71d-42f1-a6a3-752cb7b3d0dd)
Observe here the constructor in SerializedHubMessage.cs:27 that is used by Redis backplane. No assignment of Message property.![image](https://github.com/dotnet/aspnetcore/assets/68167947/43120aec-ec28-49e9-b785-4f7102f3a842)
Observe here how MessageBuffer.cs:161 checks message using![image](https://github.com/dotnet/aspnetcore/assets/68167947/4d08aa6c-5e54-4bf3-bf6f-7f263f34e721)
is
operator that will yield false as it is null, not incrementing the sequence Id as it should have.