Skip to content

all goroutines are dead asleep - deadlock! wasm docs #426

Open
@otaxhu

Description

@otaxhu

I'm trying to do the next:

Client Code:

//go:build js && wasm

package main

import (
	"context"
	"log"
	"syscall/js"

	"nhooyr.io/websocket"
)

func main() {
	ctx := context.Background()
	window := js.Global()
	window.Set("goWS", js.FuncOf(func(_ js.Value, args []js.Value) any {
		conn, _, err := websocket.Dial(ctx, args[0].String(), nil)
		if err != nil {
			log.Fatal(err)
		}
		goWSObject := window.Get("goWS")
		goWSObject.Set("send", js.FuncOf(func(_ js.Value, args []js.Value) any {
			if err := conn.Write(ctx, websocket.MessageText, []byte(args[0].String())); err != nil {
				log.Fatal(err)
			}
			return nil
		}))
		goWSObject.Set("waitMessage", js.FuncOf(func(_ js.Value, _ []js.Value) any {
			_, bb, err := conn.Read(ctx)
			if err != nil {
				log.Fatal(err)
			}
			return bb
		}))
		return nil
	}))
	waitCh := make(chan struct{})
	<-waitCh
}

index.html:

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title>goWS</title>
	<script src="/assets/wasm_exec.js"></script>
	<script>
		const go = new Go();
		WebAssembly.instantiateStreaming(fetch("/assets/app.wasm"), go.importObject)
			.then(res => go.run(res.instance))
	</script>
</head>
<body>
</body>
</html>

Server code:

package main

import (
	"context"
	"net/http"

	"nhooyr.io/websocket"
)

func main() {
	ctx := context.Background()

	http.HandleFunc("/ws-chat", func(w http.ResponseWriter, r *http.Request) {
		conn, err := websocket.Accept(w, r, &websocket.AcceptOptions{
			InsecureSkipVerify: true,
		})
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		_, bb, err := conn.Read(ctx)
		if err != nil {
			conn.Close(websocket.StatusInternalError, err.Error())
			return
		}
		wr, err := conn.Writer(ctx, websocket.MessageText)
		if err != nil {
			conn.Close(websocket.StatusInternalError, err.Error())
			return
		}
		wr.Write(bb)
		wr.Close()
		conn.CloseNow()
	})
	http.ListenAndServe(":8080", http.DefaultServeMux)
}

Also I'm going to attach my Makefile so you can see the commands when I'm compiling:

build_client:
	GOOS=js GOARCH=wasm go build -o dist/assets/app.wasm cmd/go-ws-client/main.go
	cp $(go env GOROOT)/misc/wasm/wasm_exec.js dist/assets/

build_server:
	go build -o dist/bin/app-server cmd/go-ws-server/main.go

Structure of dist folder:

dist/
	- assets/
		- app.wasm
		- wasm_exec.js
	- bin/
		- app-server
	- index.html

But i'm getting the following errors after calling window.goWS("ws://localhost:8080/ws-chat") from the firefox browser's console:

Console:

> window.goWS("ws://localhost:8080/ws-chat")
fatal error: all goroutines are asleep - deadlock! wasm_exec.js:22:14
<empty string>
wasm_exec.js:22:14
goroutine 1 [chan receive]: wasm_exec.js:22:14
main.main() wasm_exec.js:22:14
	/home/oscar/Escritorio/proyecto-react/cmd/go-ws-client/main.go:47 +0xc wasm_exec.js:22:14
<empty string> wasm_exec.js:22:14
goroutine 7 [select]: wasm_exec.js:22:14
nhooyr.io/websocket.dial({0x5aa80, 0x1430050}, {0x1466020, 0x1b}, 0x0) wasm_exec.js:22:14
	/home/oscar/go/pkg/mod/nhooyr.io/[email protected]/ws_js.go:320 +0x1c wasm_exec.js:22:14
nhooyr.io/websocket.Dial({0x5aa80, 0x1430050}, {0x1466020, 0x1b}, 0x0) wasm_exec.js:22:14
	/home/oscar/go/pkg/mod/nhooyr.io/[email protected]/ws_js.go:289 +0x2 wasm_exec.js:22:14
main.main.func1.1({{}, 0x0, 0x0}, {0x140e0f0, 0x1, 0x1}) wasm_exec.js:22:14
	/home/oscar/Escritorio/proyecto-react/cmd/go-ws-client/main.go:19 +0x4 wasm_exec.js:22:14
syscall/js.handleEvent() wasm_exec.js:22:14
	/usr/local/go/src/syscall/js/func.go:100 +0x26 wasm_exec.js:22:14
exit code: 2 wasm_exec.js:101:14
undefined

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions