wasmws库的websock_js.go文件中存在无效操作问题

wasmws库的websock_js.go文件中存在无效操作问题 我使用的是 go1.17.1 linux/amd64。

我想使用 gRPC 和 wasm 构建一个 Web 应用。为此,我定义了 proto 来实现服务器和客户端。然后,我就可以使用实现的函数与数据库通信,并从该数据库中获取内容来创建我的 Web 应用。以下代码包含在文件 hycli.go 中:

package hycli

import (
	"crypto/tls"
	"log"
	"net/url"
	"syscall/js"
	"time"

	"github.com/tarndt/wasmws"

	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"

	client "testGRPC/proto"
)

var (
	cli client.BackendClient
)

func Client() (cli client.BackendClient) {
	// build grpc URL
	href := js.Global().Get("location").Get("href")
	u, err := url.Parse(href.String())
	if err != nil {
		log.Fatal("invalid document location: ", href.String(), ": ", err)
	}

	if u.Scheme == "http" {
		u.Scheme = "ws"
	} else {
		u.Scheme = "wss"
	}

	u.Path = "/grpc-proxy"

	log.Print("grpc URL: ", u)

	//Dial setup
	const dialTO = 5 * time.Second
	dialCtx, _ := context.WithTimeout(context.Background(), dialTO)
	//dialCtx, dialCancel := context.WithTimeout(context.Background(), dialTO)
	//defer dialCancel()

	//Connect to remote gRPC server
	creds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
	cc, err := grpc.DialContext(dialCtx, "passthrough:///"+u.String(),
		grpc.WithContextDialer(wasmws.GRPCDialer),
		grpc.WithDisableRetry(),
		grpc.WithTransportCredentials(creds))

	if err != nil {
		log.Fatalf("Could not gRPC dial: %s; Details: %s", u.String(), err)
	}

	cli = client.NewBackendClient(cc)
	return
}

这个文件对我所有用于生成 wasm 文件的 go 文件都很有用。例如,这是 mainPage.go:

package main

import (
	"testGRPC/client/hycli"
	client "testGRPC/proto"

	//"syscall/js"
	//"time"
)

//go:generate bash -c "GOOS=js GOARCH=wasm go build -o ../src/mainPage.wasm ./mainPage.go"

var cli client.BackendClient

func main(){
	cli = hycli.Client()

	done := make(chan struct{})

	/*

        where we code javascript in go with syscall/js
       
       */


	<-done
	
}

然后,我想在模板(例如模板 index.tmpl)中使用生成的 mainPage.wasm。我尝试让一个 go 文件(mainPage.go)正常工作,但没有成功。我的运行脚本是命令 modd,其配置文件 modd.conf 如下:

modd.conf {}

go.mod go.sum **/*.go {
    prep: go build .
}

client/../*.go {
    prep: go generate ./client/...
}

testGRPC {
    daemon: ./testGRPC
}

(testGRPC 是我给 go.mod 起的名字)

当我在命令提示符中运行 modd 时,得到以下输出:

> 17:10:09: prep: go build .
>> done (198.713987ms)
17:10:10: prep: go generate ./client/...
# github.com/tarndt/wasmws
/home/dev1/go/pkg/mod/github.com/tarndt/wasmws@v0.0.0-20191230183838-0f186a886e92/websock_js.go:33:13: invalid operation: newBlob == jsUndefined (struct containing [0]func() cannot be compared)
/home/dev1/go/pkg/mod/github.com/tarndt/wasmws@v0.0.0-20191230183838-0f186a886e92/websock_js.go:39:46: invalid operation: testBlob.Get("arrayBuffer") != jsUndefined (struct containing [0]func() cannot be compared)
/home/dev1/go/pkg/mod/github.com/tarndt/wasmws@v0.0.0-20191230183838-0f186a886e92/websock_js.go:40:26: invalid operation: testBlob.Get("stream") != js.Undefined() (struct containing [0]func() cannot be compared)
client/wasm/mainPage.go:11: running "bash": exit status 2
exit status 1
17:10:10: daemon: ./testGRPC
>> starting...

我不明白为什么会出现这个错误,如果我的问题很愚蠢,我很抱歉,我是一个初学者,正在努力理解发生了什么。如果你需要更多信息来理解我的问题,请告诉我;如果你没有解决方案但能在 wasm 生成方面帮助我,请指点我,我已经在网上寻找帮助一整天了,但找不到任何我能清楚理解的东西。


1 回复

问题出现在 wasmws 库的 websock_js.go 文件中,该库使用了已弃用的 js.Undefined() 比较方式。从 Go 1.17 开始,js.Value 类型不再支持直接与 js.Undefined() 进行比较操作。

以下是修复方案:

方案1:更新 wasmws 库(推荐)

// 修改 websock_js.go 第33行
// 原代码:if newBlob == jsUndefined {
// 修改为:
if newBlob.IsUndefined() {

// 修改第39-40行
// 原代码:if testBlob.Get("arrayBuffer") != jsUndefined && testBlob.Get("stream") != js.Undefined() {
// 修改为:
if !testBlob.Get("arrayBuffer").IsUndefined() && !testBlob.Get("stream").IsUndefined() {

方案2:使用修复后的 fork 版本 修改 go.mod 文件:

replace github.com/tarndt/wasmws => github.com/your-fork/wasmws v0.0.0-fixed

方案3:临时解决方案 - 降级 Go 版本

# 使用 Go 1.16 或更早版本
go version go1.16.15 linux/amd64

完整修复示例

// websock_js.go 修复后的关键部分
const jsUndefined = js.Undefined()

func init() {
	newBlob := js.Global().Get("Blob")
	// 修复第33行
	if newBlob.IsUndefined() {
		return
	}
	
	// 创建测试对象
	testBlob := newBlob.New()
	// 修复第39-40行
	if !testBlob.Get("arrayBuffer").IsUndefined() && !testBlob.Get("stream").IsUndefined() {
		blobSupportsStreaming = true
	}
}

验证修复

# 清理缓存并重新构建
go clean -modcache
go generate ./client/...

这个错误是因为 wasmws 库使用了旧的 JavaScript 值比较方式,而 Go 1.17 更新了 syscall/js 包的 API。建议直接修改库文件或寻找已修复该问题的 fork 版本。

回到顶部