-
Notifications
You must be signed in to change notification settings - Fork 313
Implement core API for WASM #142
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
Conversation
bc1defe
to
b6caac6
Compare
@albrow is it possible you could review this? |
dc34ee5
to
cf3e427
Compare
1b7cc02
to
52ff3bf
Compare
@coadler pls review if you can |
fe9ba71
to
e301872
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good
internal/wsecho/wsecho.go
Outdated
ctx, cancel := context.WithTimeout(ctx, time.Minute) | ||
defer cancel() | ||
|
||
b := make([]byte, 32768) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you used 1 << 40
above 32 << 10
would be consistent here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also just realized 1 << 40 is a terabyte, not a gigabyte lol.
Sure. Should be able to review tomorrow. |
ab3489c
to
06aa2f7
Compare
6d131b8
to
a9618cb
Compare
ci/wasm.sh
Outdated
GOOS=js GOARCH=wasm go test -exec=wasmbrowsertest ./... -args "$WS_ECHO_SERVER_URL" | ||
|
||
kill %1 | ||
wait -n || true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will improve this test to assert proper closure of the connection.
Going to merge for now since I want to restructure the codebase but please review if you can @albrow. I'll fix anything you point out afterwards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nhooyr looks pretty good overall. I just left some comments about build tags and not blocking inside of js.FuncOf
.
Is there any plan to implement io.ReadWriteCloser
on top of this API? that would be really helpful for a variety of use cases.
- First class [context.Context](https://blog.golang.org/context) support | ||
- Thorough tests, fully passes the [autobahn-testsuite](https://github.com/crossbario/autobahn-testsuite) | ||
- [Zero dependencies](https://godoc.org/nhooyr.io/websocket?imports) | ||
- JSON and ProtoBuf helpers in the [wsjson](https://godoc.org/nhooyr.io/websocket/wsjson) and [wspb](https://godoc.org/nhooyr.io/websocket/wspb) subpackages | ||
- Highly optimized by default | ||
- Concurrent writes out of the box | ||
- [Complete WASM](https://godoc.org/nhooyr.io/websocket#hdr-WASM) support |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This is an abbreviation (not an acronym) so it's usually spelled "Wasm".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
func (c *WebSocket) addEventListener(eventType string, fn func(e js.Value)) { | ||
c.v.Call("addEventListener", eventType, js.FuncOf(func(this js.Value, args []js.Value) interface{} { | ||
func (c WebSocket) addEventListener(eventType string, fn func(e js.Value)) func() { | ||
f := js.FuncOf(func(this js.Value, args []js.Value) interface{} { | ||
fn(args[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's really important to not block inside of a js.Func
wrapped function. Doing so will block the JavaScript event loop and prevent any other JavaScript functions from running. You should almost always start a new goroutine inside of js.FuncOf
.
For example:
f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go fn(args[0])
return nil
})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, fixed.
func (c *WebSocket) SendText(v string) (err error) { | ||
// SendText sends the given string as a text message | ||
// on the WebSocket. | ||
func (c WebSocket) SendText(v string) (err error) { | ||
defer handleJSError(&err, nil) | ||
c.v.Call("send", v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have good test coverage for the SendText
method? I've had a lot of trouble with things like this in the past because JavaScript does wonky and unexpected things with text encoding. The string you are trying to send might not end up being the same as what is received on the other end. It might even be better to just remove this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have good test coverage here. See https://github.com/nhooyr/websocket/blob/ef5a88d1828ab3da40b07b9faacf627b0421b329/websocket_js_test.go#L39
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nhooyr it looks like randString
only includes hex characters? You should probably test with more unicode characters, in particular ones with higher code points. There can be differences in how these are encoded/interpreted in Go and JavaScript.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair. I'll adjust it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in #148
@@ -0,0 +1,217 @@ | |||
package websocket // import "nhooyr.io/websocket" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this file have the build tag: +build js,wasm
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Files with _js are automatically compiled only for GOOS=js.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👌 Combined with the other thread about not needing wasm
in the build tags, this should be fine.
@@ -0,0 +1,58 @@ | |||
// +build js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless you know that a file is compatible with GopherJS you usually want to use the build tag +build js,wasm
. The addition of wasm
clarifies for the Go compiler that this file is compatible with WebAssembly but tells the GopherJS compiler that the file is not compatible with GopherJS. This blog post explains the situation in a little more detail.
Basically it works like this:
Build tag | Vanilla Go | WebAssembly | GopherJS |
---|---|---|---|
(none) | ✅ | ✅ | ✅ |
js |
❌ | ✅ | ✅ |
!js |
✅ | ❌ | ❌ |
js,wasm |
❌ | ✅ | ❌ |
js,!wasm |
❌ | ❌ | ✅ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The library should just work with GopherJS once gopherjs/gopherjs#929 is closed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It won't even compile on GopherJS versions that don't support Go 1.13 because we use the new wrapping functions in the errors package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reason being syscall/js is shimmed by GopherJS so that it works the same as Go Wasm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha. Seems fine if you are not supporting versions older than 1.13.
Already implemented. websocket.NetConn is compiled into Wasm builds. |
In this PR it wasn't but I made it work in follow up PR #146 |
Closes #121