Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[browser][webSocket] Data Loss in ClientWebSocket.ReceiveAsync after server initiated close #96359

Closed
imxcstar opened this issue Dec 29, 2023 · 14 comments
Assignees
Labels
arch-wasm WebAssembly architecture area-System.Net os-browser Browser variant of arch-wasm
Milestone

Comments

@imxcstar
Copy link

Description

In a C# Blazor WebAssembly (WASM) application where multiple threads aren't utilized, there's an issue with the ClientWebSocket's ReceiveAsync method. Initially, data is received successfully. However, due to extended processing time for preceding data, the server disconnects before subsequent data can be retrieved using ReceiveAsync. Strangely, at the JavaScript layer, it's evident that the subsequent data has arrived (confirmed via WebSocket data in browser network captures). How can this scenario be effectively addressed?

Reproduction Steps

  1. Establish a ClientWebSocket connection in a C# Blazor WebAssembly application.
  2. Begin receiving data using the ReceiveAsync method.
  3. Process the initially received data that might take an extended period.
  4. While processing, allow enough time for additional data to arrive from the server.
  5. Observe that due to the prolonged processing time, the server disconnects before the processing completes.
  6. Monitor the WebSocket traffic using browser network tools to confirm the arrival of subsequent data.
    demo git

Expected behavior

  • The ClientWebSocket's ReceiveAsync method should continuously receive and buffer incoming data, irrespective of the time taken for processing previously received data.
  • Even if there's a delay in handling the initial data, subsequent data should be accessible via ReceiveAsync, allowing uninterrupted data reception.

Actual behavior

  • Initial data is received successfully through ReceiveAsync.
  • However, when processing takes an extended duration, the server disconnects, and subsequent data becomes inaccessible via ReceiveAsync.
  • Browser network captures indicate the arrival of subsequent data, which isn't retrievable due to the disconnection issue.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Dec 29, 2023
@ghost
Copy link

ghost commented Dec 29, 2023

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

In a C# Blazor WebAssembly (WASM) application where multiple threads aren't utilized, there's an issue with the ClientWebSocket's ReceiveAsync method. Initially, data is received successfully. However, due to extended processing time for preceding data, the server disconnects before subsequent data can be retrieved using ReceiveAsync. Strangely, at the JavaScript layer, it's evident that the subsequent data has arrived (confirmed via WebSocket data in browser network captures). How can this scenario be effectively addressed?

Reproduction Steps

  1. Establish a ClientWebSocket connection in a C# Blazor WebAssembly application.
  2. Begin receiving data using the ReceiveAsync method.
  3. Process the initially received data that might take an extended period.
  4. While processing, allow enough time for additional data to arrive from the server.
  5. Observe that due to the prolonged processing time, the server disconnects before the processing completes.
  6. Monitor the WebSocket traffic using browser network tools to confirm the arrival of subsequent data.
    demo git

Expected behavior

  • The ClientWebSocket's ReceiveAsync method should continuously receive and buffer incoming data, irrespective of the time taken for processing previously received data.
  • Even if there's a delay in handling the initial data, subsequent data should be accessible via ReceiveAsync, allowing uninterrupted data reception.

Actual behavior

  • Initial data is received successfully through ReceiveAsync.
  • However, when processing takes an extended duration, the server disconnects, and subsequent data becomes inaccessible via ReceiveAsync.
  • Browser network captures indicate the arrival of subsequent data, which isn't retrievable due to the disconnection issue.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Author: imxcstar
Assignees: -
Labels:

area-System.Net, untriaged

Milestone: -

@MihaZupan MihaZupan added the os-browser Browser variant of arch-wasm label Dec 29, 2023
@wfurt wfurt added the arch-wasm WebAssembly architecture label Dec 30, 2023
@ghost
Copy link

ghost commented Dec 30, 2023

Tagging subscribers to 'arch-wasm': @lewing
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

In a C# Blazor WebAssembly (WASM) application where multiple threads aren't utilized, there's an issue with the ClientWebSocket's ReceiveAsync method. Initially, data is received successfully. However, due to extended processing time for preceding data, the server disconnects before subsequent data can be retrieved using ReceiveAsync. Strangely, at the JavaScript layer, it's evident that the subsequent data has arrived (confirmed via WebSocket data in browser network captures). How can this scenario be effectively addressed?

Reproduction Steps

  1. Establish a ClientWebSocket connection in a C# Blazor WebAssembly application.
  2. Begin receiving data using the ReceiveAsync method.
  3. Process the initially received data that might take an extended period.
  4. While processing, allow enough time for additional data to arrive from the server.
  5. Observe that due to the prolonged processing time, the server disconnects before the processing completes.
  6. Monitor the WebSocket traffic using browser network tools to confirm the arrival of subsequent data.
    demo git

Expected behavior

  • The ClientWebSocket's ReceiveAsync method should continuously receive and buffer incoming data, irrespective of the time taken for processing previously received data.
  • Even if there's a delay in handling the initial data, subsequent data should be accessible via ReceiveAsync, allowing uninterrupted data reception.

Actual behavior

  • Initial data is received successfully through ReceiveAsync.
  • However, when processing takes an extended duration, the server disconnects, and subsequent data becomes inaccessible via ReceiveAsync.
  • Browser network captures indicate the arrival of subsequent data, which isn't retrievable due to the disconnection issue.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Author: imxcstar
Assignees: -
Labels:

arch-wasm, area-System.Net, untriaged, os-browser

Milestone: -

@lewing lewing assigned kg Jan 3, 2024
@lewing
Copy link
Member

lewing commented Jan 3, 2024

cc @pavelsavara

@lewing lewing added this to the 9.0.0 milestone Jan 3, 2024
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jan 3, 2024
@pavelsavara
Copy link
Member

I think we are talking about blocking UI thread for too long.
Are you saying that doing the same with just JS (no dotnet) would not drop the WS connection ?
Demo of that would be helpful.

@kg
Copy link
Contributor

kg commented Jan 3, 2024

Yes, if you block the main thread for long enough your connection may drop. This isn't something we can fix if it's due to blocking the main thread. However, future optimizations may make your processing fast enough to avoid dropping the connection on faster machines. Have you tested using AOT?

@pavelsavara
Copy link
Member

pavelsavara commented Jan 3, 2024

More questions

  • what browsers you tested with ?
  • what client OS/device ?
  • how long does it take for the server to give up ?
  • I don't see any option to configure client side timeout, perhaps server could be configured ?
  • does the server send any keep-alive pings ?
  • what is the server side technology and hosting in this case ?

@pavelsavara pavelsavara added the needs-author-action An issue or pull request that requires more info or actions from the author. label Jan 3, 2024
@ghost
Copy link

ghost commented Jan 3, 2024

This issue has been marked needs-author-action and may be missing some important information.

@imxcstar
Copy link
Author

imxcstar commented Jan 4, 2024

I think we are talking about blocking UI thread for too long. Are you saying that doing the same with just JS (no dotnet) would not drop the WS connection ? Demo of that would be helpful.

More questions

  • what browsers you tested with ?
  • what client OS/device ?
  • how long does it take for the server to give up ?
  • I don't see any option to configure client side timeout, perhaps server could be configured ?
  • does the server send any keep-alive pings ?
  • what is the server side technology and hosting in this case ?

@pavelsavara
The problem I encountered is that in dotnet blazer wasm, I use ClientWebSocket to receive data from the websocket server, and then I block the UI thread (or asynchronously) to process the data. During the processing of this data, the websocket server will send subsequent data, and then the websocket server will automatically disconnect. After the previous data is processed, There will be no way to obtain subsequent data (but the websocket server has already sent the subsequent data before disconnecting). The same problem does not occur when using JavaScript (without dotnet), and I also blocked the UI thread, which is shown in the demo.

  • I used Edge browser for testing
  • The websocket server will disconnect very quickly after sending data
  • The websocket server is provided by a third party and cannot be configured

Yes, if you block the main thread for long enough your connection may drop. This isn't something we can fix if it's due to blocking the main thread. However, future optimizations may make your processing fast enough to avoid dropping the connection on faster machines. Have you tested using AOT?

@kg
I did not use AOT. After all, the size has increased significantly after using AOT...

@ghost ghost added needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration and removed needs-author-action An issue or pull request that requires more info or actions from the author. labels Jan 4, 2024
@pavelsavara pavelsavara assigned pavelsavara and unassigned kg Jan 4, 2024
@pavelsavara pavelsavara removed the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Jan 4, 2024
@pavelsavara
Copy link
Member

pavelsavara commented Jan 4, 2024

So, this is not about CPU hog or about timeouts.
This is about WS close event dropping the pending incoming messages ?
Or part of the message ?
You are testing with Net8, right ?

@imxcstar
Copy link
Author

imxcstar commented Jan 4, 2024

So, this is not about CPU hog or about timeouts. This is about WS close event dropping the pending incoming messages ? Or part of the message ? You are testing with Net8, right ?

Yes, I am using Net8 for testing. After the websocket server is disconnected, ClientWebSocket ReceiveAsync cannot read messages that were not read before the disconnection.

@pavelsavara
Copy link
Member

I confirmed that my implementation in Net7, Net8 was too naive, sorry.
I'm working on fix for Net9 as part of larger refactoring.

Will see how easy it would be to backport to Net8 bit later.

@pavelsavara pavelsavara changed the title Handling Data Loss in ClientWebSocket ReceiveAsync in C# Blazor WASM [browser][webSocket] Data Loss in ClientWebSocket.ReceiveAsync after server initiated close Jan 9, 2024
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jan 14, 2024
pavelsavara added a commit to pavelsavara/runtime that referenced this issue Jan 15, 2024
@pavelsavara pavelsavara mentioned this issue Jan 15, 2024
@pavelsavara
Copy link
Member

@imxcstar could you please validate that the issue is fixed for Net9 ?
You can download https://aka.ms/dotnet/9.0.1xx/daily/dotnet-sdk-win-x64.zip it should contain the fix #99612 by tomorrow.
We are still working on proper fix for Net8 here #99673

cc @ilonatommy

@imxcstar
Copy link
Author

@pavelsavara alright, everything's sorted out now. 😀

@pavelsavara
Copy link
Member

Fixed by #99673

@github-actions github-actions bot locked and limited conversation to collaborators May 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
arch-wasm WebAssembly architecture area-System.Net os-browser Browser variant of arch-wasm
Projects
None yet
Development

No branches or pull requests

6 participants