Проблема с подключением веб-сокета из c ++, скомпилированного с emscripten - PullRequest
1 голос
/ 22 апреля 2019

Попытка подключения к веб-сокету (poco-1.9.0 samples \ WebSocketServer) с использованием кода c ++, скомпилированного с emscripten. Использование скомпилированного 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 голосов
/ 22 апреля 2019

Я всегда говорю людям, которые пробуют WebAssembly, что ...

WebAssembly (в контексте браузера) - это JavaScript.

Даже если вы кодируете на C / C ++с использованием Emscripten скомпилированный WebAssembly байт-код запускается в JavaScript-движке браузера, таком как V8.Это означает, что код WASM не имеет никаких специальных низкоуровневых API-интерфейсов, кроме API-интерфейсов JavaScript.Все функции системного уровня эмулируются с использованием 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.

Ссылки, связанные с данной:

...