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

时间:2019-04-22 13:34:43

标签: c++ boost emscripten webassembly

尝试使用通过emscripten编译的c ++代码连接到websocket(poco-1.9.0示例\ 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的异步调用?

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

1 个答案:

答案 0 :(得分:0)

我总是告诉尝试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 websocket,因此您只能使用异步(非阻塞)套接字操作。

相关参考文献: