-
Notifications
You must be signed in to change notification settings - Fork 297
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
all goroutines are dead asleep - deadlock! wasm docs #426
Comments
Unrelated to this library, see golang/go#41310 |
I don't know if you are too busy af but I found the answer and I don't know if you have the time to create an example of a ping pong websocket client compiled in WASM. So what I did was to require a callback, passing the message as an argument, the reason is because of async nature of //go:build js && wasm
package main
import (
"context"
"syscall/js"
"nhooyr.io/websocket"
)
func main() {
ctx := context.Background()
conn, _, err := websocket.Dial(ctx, "ws://localhost:8080/ping-pong", nil)
if err != nil {
panic(err)
}
wr, err := conn.Writer(ctx, websocket.MessageText)
if err != nil {
panic(err)
}
js.Global().Set("sendMessageGo", js.FuncOf(func(_ js.Value, args []js.Value) any {
// args[0] is the string that want to sent to the server
wr.Write([]byte(args[0].String()))
wr.Close()
// spawning a goroutine because of conn.Read() is async, and js functions cannot wait
go func() {
_, bb, err := conn.Read(ctx)
if err != nil {
panic(err)
}
// args[1] is the callback, has the shape (bytes) => {/* any operation with the bytes */}
// passing to the callback the bytes in string format
args[1].Invoke(string(bb))
}()
// the js functions must return inmediatly, cannot wait for async operations
return nil
}))
waitCh := make(chan struct{})
<-waitCh
} |
Hmm weird. I have this test here which runs in WASM and requires no extra goroutines. https://github.com/nhooyr/websocket/blob/master/ws_js_test.go I'm def a little busy to look into exactly what's going on in your example. I'll open this up again and look into it later. |
don't worry, I saw in the tests that you are not testing the |
No it is, see this line https://github.com/nhooyr/websocket/blob/e3a2d32f704fb06c439e56d2a85334de04b50d32/ws_js_test.go#L32 It writes a message and then confirms the same message is read back. |
forget it, you are in fact reading in the wstest.Echo, but I think it has something to do when you are binding the Go function with the JS function |
I tried this other example and also worked, with Promise object instead of callback for compatibility with //go:build js && wasm
package main
import (
"context"
"syscall/js"
"nhooyr.io/websocket"
)
func main() {
ctx := context.Background()
conn, _, err := websocket.Dial(ctx, "ws://localhost:8080/ws-chat", nil)
if err != nil {
panic(err)
}
js.Global().Set("sendMessageGo", js.FuncOf(func(_ js.Value, args []js.Value) any {
wr, err := conn.Writer(ctx, websocket.MessageText)
if err != nil {
panic(err)
}
wr.Write([]byte(args[0].String()))
wr.Close()
// returning a Promise
return js.Global().Get("Promise").New(js.FuncOf(func(_ js.Value, args []js.Value) any {
// args[0] is resolve callback
// args[1] is reject callback
// spawining a goroutine because of conn.Read() blocking nature
go func() {
_, bb, err := conn.Read(ctx)
if err != nil {
// if there is an error, reject the promise, calling the reject callback
args[1].Invoke(err.Error())
return
}
// if there is no error then pass to resolve the bytes that comes from the server
args[0].Invoke(string(bb))
}()
// also the constructor must return inmediatly, cannot wait for async operations
return nil
}))
}))
waitCh := make(chan struct{})
<-waitCh
} |
Ah yes I see, you probably can't block in a JS callback so you have to return a promise. That makes sense. We can document it for sure. See also https://www.reddit.com/r/WebAssembly/comments/nm69e8/blocking_calls_in_wasm/ |
I'm trying to do the next:
Client Code:
index.html
:Server code:
Also I'm going to attach my Makefile so you can see the commands when I'm compiling:
Structure of
dist
folder:But i'm getting the following errors after calling
window.goWS("ws://localhost:8080/ws-chat")
from the firefox browser's console:Console:
The text was updated successfully, but these errors were encountered: