从使用 emscripten 编译的 C++ 连接 websocket 时出现问题
Problem connecting websocket from c++ compiled with emscripten
正在尝试使用由 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。
相关参考:
正在尝试使用由 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。
相关参考: