网络

使用 Emscripten 编译的应用程序可以通过多种方式连接到在线服务器。查看此处的子主题以了解可用的不同策略。

如果您熟悉不同的 Web API 提供的网络概念,例如 XmlHttpRequest、Fetch、WebSockets 和 WebRTC,您可以通过利用您已经了解的内容快速入门:从 C/C++ 代码调用 JavaScript(参见“连接 C++ 和 JavaScript”部分),您可以通过编写常规 JavaScript 建立网络连接。对于 C/C++ 开发人员,Emscripten 提供了几种方法,此处进行了介绍。

Emscripten WebSockets API

WebSockets API 为浏览器提供面向连接的消息帧双向异步网络通信。它是 Web 上最接近 TCP 的东西,网站可以访问,Web 浏览器无法直接访问 TCP 套接字。

Emscripten 为从 C/C++ 代码访问 WebSockets API 提供了一个直通 API。这对于希望避免编写任何 JavaScript 代码或处理 C/C++ 和 JavaScript 语言互操作的开发人员非常有用。有关详细信息,请参见系统包含文件 <emscripten/websocket.h>。Emscripten WebSockets API 相对于在 JavaScript 中手动访问 WebSockets 的一个好处是能够跨多个线程共享对 WebSocket 句柄的访问,这对于从头开始开发来说可能很费时。

要针对 Emscripten WebSockets API,您必须使用 -lwebsocket.js 链接器指令将其链接进来。

通过 WebSockets 模拟 POSIX TCP 套接字

如果您有使用 Posix Sockets API 编写的现有 TCP 网络代码,默认情况下,Emscripten 尝试模拟此类连接,以通过 WebSocket 协议进行连接。为此,您需要在服务器端使用类似 WebSockify 的东西来启用 TCP 服务器堆栈接收传入的 WebSocket 连接。目前这种模拟并不完整,您很可能会在开箱即用时遇到问题,并且需要调整代码以适应这种模拟提供的限制。

这是 Emscripten 的默认构建模式。使用链接器标志 -sWEBSOCKET_URLModule['websocket']['url'] 指定要连接到的 WebSocket URL,以及链接器标志 -sWEBSOCKET_SUBPROTOCOLModule['websocket']['subprotocol'] 来控制连接类型 ('binary''text')。

通过 WebSocket 代理服务器实现完整的 POSIX 套接字

Emscripten 提供了一个本机 POSIX 套接字代理服务器程序,位于目录 tools/websocket_to_posix_proxy/ 中,该程序允许从 Web 浏览器访问完整的 POSIX 套接字 API。此支持通过将来自浏览器的所有 POSIX 套接字 API 调用代理到 Emscripten POSIX 套接字代理服务器(通过透明使用 WebSockets API),然后代理服务器代表页面执行本机 TCP/UDP 调用来工作。这允许 Web 浏览器页面运行完整的 TCP 和 UDP 连接,充当接受传入连接的服务器,并执行主机名查找和反向查找。由于所有 API 调用都被单独代理,因此此支持可能很慢。此支持主要用于开发测试基础设施和调试。

以下 POSIX 套接字函数以这种方式代理
  • socket()socketpair()shutdown()bind()connect()listen()accept()getsockname()getpeername()send()recv()sendto()recvfrom()sendmsg()recvmsg()getsockopt()setsockopt()getaddrinfo()getnameinfo()

以下 POSIX 套接字函数目前未被代理(并且无法工作)
  • poll()close()(使用 shutdown() 代替)、select()

要使用 POSIX 套接字代理,请使用标志 -lwebsocket.js -sPROXY_POSIX_SOCKETS -pthread -sPROXY_TO_PTHREAD 链接应用程序。也就是说,POSIX 套接字代理建立在 Emscripten WebSockets 库之上,并且需要多线程并将应用程序 main() 代理到 pthread。

有关 POSIX 套接字代理服务器如何在 Emscripten 客户端程序中工作的示例,请参见文件 test/websocket/tcp_echo_client.c

XmlHttpRequests 和 Fetch API

对于 HTTP 传输,可以使用浏览器内置的 XmlHttpRequest (XHR) API 和较新的 Fetch API。这些可以直接从 JavaScript 访问。Emscripten 还提供直通 API 来执行 HTTP 请求。有关更多信息,请参见 emscripten_async_wget*() C API 和 Emscripten Fetch API。

WebRTC 和 UDP

浏览器中无法直接进行 UDP 通信,但作为一种替代方案,WebRTC 规范提供了一种使用 WebRTC 数据通道进行 UDP 类似通信的机制。目前,Emscripten 未提供用于与 WebRTC 交互的 C/C++ API。