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 Improvements #44614

Closed
lewing opened this issue Nov 12, 2020 · 12 comments · Fixed by #58199
Closed

Browser WebSocket Improvements #44614

lewing opened this issue Nov 12, 2020 · 12 comments · Fixed by #58199
Assignees
Labels
arch-wasm WebAssembly architecture area-System.Net
Milestone

Comments

@lewing
Copy link
Member

lewing commented Nov 12, 2020

The current Browser ClientWebSocket implementation is using managed side buffering of partial writes, we should review wether we can push the writes to the browser and chain all the data there for the send call.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Net untriaged New issue has not been triaged by the area owner labels Nov 12, 2020
@ghost
Copy link

ghost commented Nov 12, 2020

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


Issue meta data
Issue content:
The current Browser ClientWebSocket implementation is using managed side buffering of partial writes, we should review the wether we can push the writes to to the browser and chain a the data there for the send call.

</td>
Issue author: lewing
Assignees: -
Labels:
`area-System.Net`, `untriaged`

</td>
Milestone: -

@lewing lewing added arch-wasm WebAssembly architecture and removed untriaged New issue has not been triaged by the area owner labels Nov 12, 2020
@lewing
Copy link
Member Author

lewing commented Nov 12, 2020

cc @kjpou1 @kg

@kg
Copy link
Contributor

kg commented Nov 12, 2020

We should just push it directly to the browser, I don't see any reason to do unnecessary work on the managed side unless it's addressing a bottleneck we found in a profiler.

@lewing
Copy link
Member Author

lewing commented Nov 13, 2020

No, the issue is just the api mismatch and we can track the write buffers on the browser side rather than in managed for the fragmented send.

@lewing lewing added this to the 6.0.0 milestone Nov 13, 2020
@lewing
Copy link
Member Author

lewing commented Nov 22, 2020

Yeah, looking closer at the spec it appears we should: (edited - corrected some errors in the previous review)

  • Get tests in place Browser WebSockets tests #44666
  • Move all buffering to unmanaged, either as a chained blob or an array of write buffers.
  • Validate when the send Task should complete (should it be after we've posted it or after the writeBuffer in the browser is empty, should it vary based on endOfMessage?)
  • Review the expectations for the other states
  • Review exception types
  • Implement IWebProxy support

@lewing lewing changed the title Browser WebSocket buffering Browser WebSocket Improvements Nov 29, 2020
@lewing
Copy link
Member Author

lewing commented Nov 29, 2020

cc @kjpou1

@kjpou1
Copy link
Contributor

kjpou1 commented Nov 30, 2020

Looking at it

@kjpou1
Copy link
Contributor

kjpou1 commented Dec 1, 2020

So far looking at sample streams of chained blob and an array of write buffers.

Have not found a way to control the websocket text or string send type when using the above. It is always sent as binary.

WebSocketMessageType

Type Value Desc
Binary 1 The message is in binary format.
Close 2 A receive has completed because a close message was received.
Text 0 The message is clear text.

What controls this with fetch is the type of buffer that is passed.

Type Data structure sent with fetch
Binary Uint8Array
Text string

This also controls how we receive data from a websocket using the same criteria. If the fetch body is text then we signify text and a blob or array buffer sent back is read and transferred back to the client as binary.

@lewing
Copy link
Member Author

lewing commented Dec 1, 2020

I added that distinction to #44666 lets start by getting some tests in place so that we can validate any changes.

@lewing
Copy link
Member Author

lewing commented Apr 15, 2021

cc @pavelsavara

@pavelsavara
Copy link
Member

WebSocketStream would be nice if it was ready, but it is not.

@pavelsavara
Copy link
Member

pavelsavara commented Aug 25, 2021

Thinking about design for send buffers:

when the endOfMessage == false

  • We have to make copy anyway, as the C# owner of the buffer could rewrite it with new data.
  • This copy needs to be done before we return the promise/Task.
  • This promise would not be blocking on network, instead we would queue the buffer copy on the JS side.
  • The queue would be stored new __pending_send_buffers__ property of the WS instance.

when the endOfMessage == true and there are queued partial messages.

  • we need to concatenate all buffers in the __pending_send_buffers__ queue and then WebSocket.send it
  • This call should also block the promise until WebSocket.bufferedAmount === 0, probably by polling from setTimeout 50ms

when the endOfMessage == true and there are NO queued partial messages.

  • because WebSocket.send does copy of the buffer, we don't have to . We could directly pass Module.HEAPU8.subarray() as seen in our typedarray_copy_from.
  • This call should also block the promise until WebSocket.bufferedAmount === 0, probably by polling from setTimeout 50ms

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Aug 26, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Sep 18, 2021
@karelz karelz modified the milestones: Future, 7.0.0 Sep 22, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Nov 3, 2021
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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants