Skip to content

[browser][wasm] Wasm websockets support#37962

Merged
lewing merged 62 commits intodotnet:masterfrom
kjpou1:wasm-websockets
Jul 2, 2020
Merged

[browser][wasm] Wasm websockets support#37962
lewing merged 62 commits intodotnet:masterfrom
kjpou1:wasm-websockets

Conversation

@kjpou1
Copy link
Contributor

@kjpou1 kjpou1 commented Jun 16, 2020

No description provided.

@ghost
Copy link

ghost commented Jun 16, 2020

Tagging subscribers to this area: @dotnet/ncl
Notify danmosemsft if you want to be subscribed.

@kjpou1 kjpou1 requested review from lewing, marek-safar and vargaz June 16, 2020 11:11
@kjpou1 kjpou1 marked this pull request as ready for review June 18, 2020 14:43

namespace System.Net.WebSockets
{
internal sealed class ReceivePayload
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this type used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used by BrowserWebSocket.cs to handle the received message queue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be readonly struct

kjpou1 added 5 commits June 19, 2020 07:31
- change accessor of _requestedSubProtocols to private
- condition more code in WebSocketHandle.Managed.cs to not access _requestedSubProtocols
@lewing lewing added this to the 5.0.0 milestone Jun 22, 2020
…websockets

# Conflicts:
#	src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj
#	src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs
@kjpou1
Copy link
Contributor Author

kjpou1 commented Jun 24, 2020

@marek-safar @stephentoub ping for a review when available.


namespace System.Net.WebSockets
{
internal sealed class ReceivePayload
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be readonly struct

@@ -0,0 +1,117 @@
// Licensed to the .NET Foundation under one or more agreements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to specialize this file for the browser? Or instead could ClientWebSocket.ConnectAsync just throw PNSE if it finds options set that aren't supported?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list of dependencies from the desktop version is much bigger (size savings) but it'd be nice to extract the common code to the shared file

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list of dependencies from the desktop version is much bigger (size savings)

Only if the consumer uses them, though, right? Otherwise we should be able to ensure the relevant stuff is linked away?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes if we don't call them internally, for example, to check if there were set.

kjpou1 and others added 6 commits July 1, 2020 11:11
…ockets/BrowserWebSockets/BrowserWebSocket.cs

Co-authored-by: campersau <buchholz.bastian@googlemail.com>
…ockets/BrowserWebSockets/BrowserWebSocket.cs

Co-authored-by: campersau <buchholz.bastian@googlemail.com>
kjpou1 and others added 5 commits July 1, 2020 15:31
…ockets.Client.csproj

Co-authored-by: Maxim Lipnin <mlipnin@gmail.com>
…ockets.Client.csproj

Co-authored-by: Maxim Lipnin <mlipnin@gmail.com>
…ockets.Client.csproj

Co-authored-by: Maxim Lipnin <mlipnin@gmail.com>
…ockets.Client.csproj

Co-authored-by: Maxim Lipnin <mlipnin@gmail.com>

WebSocketValidate.ValidateArraySegment(buffer, nameof(buffer));

_writeBuffer ??= new MemoryStream();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional? Caling SendAsync repeatably will grow MemoryStream with no limit

Copy link
Contributor Author

@kjpou1 kjpou1 Jul 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The write buffer is nulled out below so it will be recreated.

            MemoryStream writtenBuffer = _writeBuffer;
            _writeBuffer = null;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then why do you need ??=

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the message needs to be buffered until end of message is reached. Once end of message is reached it gets nulled out and needs to be recreated.

Copy link
Contributor

@marek-safar marek-safar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from me. @stephentoub could you do another pass

_writeBuffer.Write(buffer.Array!, buffer.Offset, buffer.Count);

if (!endOfMessage)
return Task.CompletedTask;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The browser websocket API isn't capable of sending messages split over multiple fragments? The endOfMessage argument elsewhere translates into the FIN bit in the websocket frame.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not have access to the websocket frame through the browser api. Also, from my understanding there is not the concept of EndOfMessage. Not that I can find anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send expects the full message so we need to buffer somewhere. An alternative to the MemoryStream buffer would be constructing a chain of Blobs on the JS side and calling send on that when endOfMessage is true.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine for the buffering to be in managed. I was questioning the buffering all-up, but if the websocket API doesn't support fragments, then ok.

kjpou1 and others added 3 commits July 2, 2020 16:45
…ockets/BrowserWebSockets/BrowserWebSocket.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
…ockets/BrowserWebSockets/BrowserWebSocket.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
…ockets/BrowserWebSockets/BrowserWebSocket.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
@lewing lewing merged commit 9715a9c into dotnet:master Jul 2, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
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 this pull request may close these issues.

8 participants