c++ - 从使用 emscripten 编译的 C++ 连接 websocket 时出现问题

标签 c++ boost emscripten webassembly

尝试使用由 emscripten 编译的 C++ 代码连接到 websocket (poco-1.9.0 samples\WebSocketServer)。使用已编译的 boost 1.69 和一个常见示例连接到套接字。

boost::asio::ssl::context ctxt(context::sslv23_client); 
ctxt.set_verify_mode(boost::asio::ssl::verify_none);

boost::asio::io_service svc;
tcp::resolver resolver(svc);
tcp::resolver::query query("127.0.0.1", "9980", 
    boost::asio::ip::resolver_query_base::numeric_service);

tcp::resolver::iterator i = resolver.resolve(query, ec);

boost::asio::ssl::stream<tcp::socket> s(svc, ctxt);
s.lowest_layer().connect(*i, ec); 
s.handshake(boost::asio::ssl::stream<tcp::socket>::client, ec);

服务器输出如下

Request from 127.0.0.1:58152: GET / HTTP/1.1
Host: 127.0.0.1:9980
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://127.0.0.1:8887
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: binary
WebSocket connection established.
Frame received (length=0, flags=0x0).
WebSocket connection closed.

但是,此代码在握手后挂起。是否可以这样使用,还是必须使用 asio 的异步调用?

此外,如果您知道任何类似的示例,请分享。

最佳答案

我总是告诉尝试 WebAssembly 的人......

WebAssembly(在浏览器上下文中)是 JavaScript。

即使您使用 Emscripten 在 C/C++ 中编写代码,编译 WebAssembly字节码在浏览器的 JavaScript 引擎(例如 V8)中运行。这意味着 WASM 代码除了 JavaScript API 之外没有任何特殊的低级 API。每个系统级功能都使用 JavaScript 模拟。

这是什么意思?设置 SSL 版本和 SSL 握手等低级套接字控制没有意义,因为您的 WASM 代码只能使用 JavaScript WebSocket API用于网络,因此套接字由浏览器处理,而不是您的 WASM 代码。

相反,您可以使用普通的 BSD 套接字。 Emscripten 会将 BSD 套接字转换为 JavaScript WebSocket。换句话说,你根本不能使用 Poco 库。

像这样:

struct sockaddr_in addr;
ing res;
int fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
unsigned long nonblocking = 1;
fcntl(fd, F_SETFL, O_NONBLOCK);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(9980);
if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) {
  perror("inet_pton failed");
  finish(EXIT_FAILURE);
}
res = connect(server.fd, (struct sockaddr *)&addr, sizeof(addr));

顺便说一句,你被迫只使用异步(非阻塞)套接字操作,因为它是 JS websockets。

相关引用:

关于c++ - 从使用 emscripten 编译的 C++ 连接 websocket 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55795238/

相关文章:

c++ - 带有 SDL 音频的 Emscripten 工作模型

c++ - 如何解释 Google 性能工具 CPU 分析器中的地址

c++ - boost协程如何在coro_t完成后检索函数返回值

c++ - Boost.MultiArray 初学者 : How to get a 4D-Array with dynamic inner-array-sizes?

c++ - boost::regex_search - boost 再次杀死了我的脑细胞

javascript - 如何使用 JavaScript 模拟 x86 无符号 32 位整数乘法?

c++ - 不能在 Qt 中使用 libclang

c++ - 如何在 C++ 14 的类中启动线程?

c++ - 使用 MKL 编译时 Eigen C++ 运行速度变慢

javascript - 如何在不复制的情况下将 canvas imageData 传递给 emscripten c++ 程序?