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 生成方面帮助我,请指点我,我已经在网上寻找帮助一整天了,但找不到任何我能清楚理解的东西。
问题出现在 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 版本。

