web页面中直接调用c++/c/go代码?【wasm】
背景
最近在做rosbag的可视化工具,网上找了个源码参考(foxglove)。成功down下来,跑起来了。于是乎,开始研究前后端代码;结果居然花了一下午没找到后端代码,不明白为什么纯web页面就可以解析rosbag(以前都是用node.js或者c++代码解析的)。
过程
在找了一下午之后,又回到了老办法;看netork,果然还是除静态资源外没找到任何一条http请求,懵逼了;但是我看到一个很奇怪的东西接下来,就开始查资料。推测解析bag的代码一定跟这个wasm有关联。
wasm介绍
WebAssembly(简称 WASM)是一种高效的、低级的字节码格式,用于在网页浏览器中运行代码。它是一种可移植的二进制格式,设计用来在Web环境中提供接近原生性能的执行速度。
WebAssembly 的特点包括:
-
高性能:WASM 可以在浏览器中接近原生代码的执行速度运行,适用于高性能计算任务,如游戏、图形处理和数据分析等。
-
可移植性:它是跨平台的,可以在任何支持 WebAssembly 的浏览器和环境中运行,不同操作系统和设备之间的兼容性很好。
-
安全性:WASM 运行在一个受限的沙箱环境中,与主机系统隔离,这样可以提高安全性,避免恶意代码对系统的破坏。
-
易于集成:它可以与 JavaScript 互操作,允许开发者将已有的 C/C++、Rust 等语言编写的代码编译为 WASM 模块,并在 Web 应用中调用这些模块。
-
快速加载:由于其紧凑的二进制格式,WASM 模块可以比传统的 JavaScript 代码加载得更快,提高了网页的响应速度。
使用场景:
- 游戏开发:由于其高性能,WASM 适用于 Web 上的游戏和图形密集型应用。
- 编译型语言的运行:可以将 C、C++、Rust 等编译成 WASM,从而在 Web 上运行这些语言的代码。
- 计算密集型任务:如图像处理、数据分析等。
总的来说,WebAssembly 提供了在 Web 环境中实现高效、可移植的代码执行的能力,是现代 Web 开发的重要组成部分。
推测
解析rosbag部分的代码必是被打包成wasm,然后web页直接调用方法了。
实现一个wasm
本机正好用go环境,于是用go实现了一下。将go打包成wasm文件,html页面直接调用:
test.go
package main
import (
"syscall/js"
)
func main() {
c := make(chan struct{}, 0)
js.Global().Set("test", js.FuncOf(func(this js.Value, p []js.Value) interface{} {
return js.ValueOf("Hello, WASM!")
}))
<-c
}
打包命令
$env:GOARCH = "wasm"
$env:GOOS = "js"
go build -o test.wasm test.go
得到一个test.wasm文件
index.html
<!DOCTYPE html>
<html>
<head>
<title>Go WASM Example</title>
</head>
<body>
<h1>Go WASM Example</h1>
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
async function loadWasm() {
try {
// 加载并实例化 WASM 模块
const wasmResponse = await fetch('test.wasm');
const wasmBuffer = await wasmResponse.arrayBuffer();
const result = await WebAssembly.instantiate(wasmBuffer, go.importObject);
// 运行 Go 实例
go.run(result.instance);
// 调用 Go 导出的函数
console.log(window.test()); // 这将输出 "Hello, WASM!"
} catch (err) {
console.error('Error loading WASM module:', err);
}
}
loadWasm();
</script>
</body>
</html>
效果
感触
是不是以后一个静态文件就可以包含前后端的代码了?