当我第一次听说 WebAssembly 以及使用 Qt 创建 Web 用户界面的可能性,就像我在普通的 C++ 中一样时,我决定深入研究这项技术。
我的开源项目 Pythonic 完全基于 Python (PyQt),我在工作中也使用 C++;因此,这个最简明、直接的 WebAssembly 教程在后端使用 Python,前端使用 C++ Qt WebAssembly。它的目标受众是像我一样不熟悉 Web 开发的程序员。

TL;DR(太长不看)
git clone https://github.com/hANSIc99/wasm_qt_example
cd wasm_qt_example
python mysite.py
然后用您喜欢的浏览器访问 http://127.0.0.1:7000。
什么是 WebAssembly?
WebAssembly(通常缩写为 Wasm)主要旨在在 Web 应用程序中执行可移植的二进制代码,以实现高性能执行。它旨在与 JavaScript 共存,并且这两个框架在同一沙箱中执行。最近的性能基准测试表明,WebAssembly 的执行速度大约快 10-40%,具体取决于浏览器,并且考虑到其新颖性,我们仍然可以期待改进。这种出色执行性能的缺点是它被广泛采用作为首选的恶意软件语言。加密货币矿工尤其受益于其性能,并且由于其二进制格式,更难检测到证据。
工具链
Qt Wiki 上有一个入门指南。我建议严格按照本指南中提到的步骤和版本进行操作。您可能需要仔细选择您的 Qt 版本,因为不同的版本具有不同的功能(例如多线程),并且每个版本都在不断改进。
要获取可执行的 WebAssembly 代码,只需将您的 Qt C++ 应用程序通过 Emscripten 即可。Emscripten 提供了完整的工具链,并且构建脚本再简单不过了
#!/bin/sh
source ~/emsdk/emsdk_env.sh
~/Qt/5.13.1/wasm_32/bin/qmake
make
构建时间大约是使用标准 C++ 编译器(如 Clang 或 g++)的 10 倍。构建脚本将输出以下文件
- WASM_Client.js
- WASM_Client.wasm
- qtlogo.svg
- qtloader.js
- WASM_Client.html
- Makefile(中间文件)
我的 (Fedora 30) 构建系统上的版本是
- emsdk: 1.38.27
- Qt: 5.13.1
前端
前端提供了一些基于 WebSocket 的功能。

- 向服务器发送消息: 使用 WebSocket 向服务器发送一个简单的字符串消息。您也可以使用简单的 HTTP POST 请求来完成此操作。
- 启动/停止定时器: 创建一个 WebSocket 并在服务器上启动一个定时器,以定期向客户端发送消息。
- 上传文件: 将文件上传到服务器,该文件将保存到运行服务器的用户的 home 目录 (~/) 中。
如果您调整代码并遇到类似这样的编译错误
error: static_assert failed due to
requirement ‘bool(-1 == 1)’ “Required feature http for file
../../Qt/5.13.1/wasm_32/include/QtNetwork/qhttpmultipart.h not available.”
QT_REQUIRE_CONFIG(http);
这意味着请求的功能不适用于 Qt Wasm。
后端
服务器工作由 Eventlet 完成。我选择 Eventlet 是因为它轻巧且易于使用。Eventlet 提供 WebSocket 功能并支持线程。

在存储库中的 mysite/template 下,有一个指向根路径中 WASM_Client.html 的符号链接。mysite/static 下的静态内容也链接到存储库的根路径。如果您调整代码并重新编译,您只需重新启动 Eventlet 即可将内容更新到客户端。
Eventlet 使用 Python 的 Web 服务器网关接口 (WSGI)。提供特定功能的函数使用装饰器进行扩展。
请注意,这是一个绝对最小的服务器实现。它不实现任何多用户功能——每个客户端都可以启动/停止定时器,即使是其他客户端也是如此。
结论
将此示例代码作为起点,以便熟悉 WebAssembly,而不会在细枝末节上浪费时间。我不对完整性或最佳实践集成做任何声明。我经历了一个漫长的学习曲线,直到我让它运行到我满意的程度,我希望这能让您简要了解这项有前途的技术。
3 条评论