emscripten-core / emscripten-core/emscripten
Unexpected error of proxyAsync with emscripten_init_websocket_to_posix_socket_bridge
- Dominant language
- C++
- Stars
- 27.6k
- Forks
- 3.6k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 105
Description
Please include the following in your bug report:
**Version of emscripten/emsdk:**
> emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.56 (cf90417346b78455089e64eb909d71d091ecc055)
clang version 19.0.0git (https:/github.com/llvm/llvm-project 34ba90745fa55777436a2429a51a3799c83c6d4c)
Target: wasm32-unknown-emscripten
Thread model: posix
**Full link command**
```
EMCC = emcc
CFLAGS = -O3 -std=c++17
EMFLAGS = -lwebsocket.js -sPROXY_POSIX_SOCKETS -pthread -sPROXY_TO_PTHREAD -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=2 -sNO_EXIT_RUNTIME=1 -sMODULARIZE -sEXPORT_NAME="WASMModule" -sEXPORTED_RUNTIME_METHODS=stringToNewUTF8
main:
$(EMCC) $(CFLAGS) $(EMFLAGS) tcp_echo_client.cpp
```
I am trying to port my socket application to WebAssembly which uses [Full POSIX Sockets over WebSocket Proxy Server](https://emscripten.org/docs/porting/networking.html#full-posix-sockets-over-websocket-proxy-server). I want to initialize the bridge only in certain case, not when the main function is loaded. So I wrap it in a function with EMSCRIPTEN_KEEPALIVE and call it in the javascript module. I made some changes based on this example test code [tcp_echo_client.c](https://github.com/emscripten-core/emscripten/blob/main/test/websocket/tcp_echo_client.c)
```cpp
// TCP client that sends a few messages to a server and prints out the replies
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef __EMSCRIPTEN__
#include
#include
#include
#include
#include
static EMSCRIPTEN_WEBSOCKET_T bridgeSocket = 0;
static pthread_t mainApplicationThreadId = 0;
emscripten::ProxyingQueue queue;
extern "C" {
EMSCRIPTEN_KEEPALIVE
void initBridgeSocket(const char *bridgeUrl) {
queue.proxyAsync(mainApplicationThreadId, [&]() {
printf("bridegeUrl = %s\n", bridgeUrl);
bridgeSocket = emscripten_init_websocket_to_posix_socket_bridge(bridgeUrl);
// Synchronously wait until connection has been established.
uint16_t readyState = 0;
do {
emscripten_websocket_get_ready_state(bridgeSocket, &readyState);
emscripten_thread_sleep(100);
} while (readyState == 0);
printf("Bridge socket ready\n");
});
queue.execute();
}
} // extern "C"
#endif
int main(int argc , char *argv[]) {
#ifdef __EMSCRIPTEN__
mainApplicationThreadId = pthread_self();
emscripten_exit_with_live_runtime();
#endif
return 0;
}
```
Then initialize a bridge when a user clicks the button.
```html
Trigger
var module;
document.addEventListener("DOMContentLoaded", async () => {
module = await WASMModule();
})
function foo() {
const bridgeUrl = document.getElementById("a").value;
module._initBridgeSocket(module.stringToNewUTF8(bridgeUrl));
}
```
**Problem:**
First, the task is still executed even without this line:
```C++
queue.execute();
```
Second, I want to make sure the bridgeUrl successfully passed into the lambda expression, so I use ```printf``` to check it. When I place it before ```emscripten_init_websocket_to_posix_socket_bridge```, It still prints the correct URL, but it gets "flushed" and becomes empty when passing into ```emscripten_init_websocket_to_posix_socket_bridge```
```
a.out.js:8 Uncaught (in promise) DOMException: Failed to construct 'WebSocket': The URL '' is invalid.
at _emscripten_websocket_new (http://127.0.0.1:3000/websocket/a.out.js:8:33075)
at __emscripten_receive_on_main_thread_js (http://127.0.0.1:3000/websocket/a.out.js:8:19685)
at http://127.0.0.1:3000/websocket/a.out.wasm:wasm-function[103]:0x5620
at http://127.0.0.1:3000/websocket/a.out.wasm:wasm-function[105]:0x5bd1
at http://127.0.0.1:3000/websocket/a.out.wasm:wasm-function[107]:0x5cd7
at http://127.0.0.1:3000/websocket/a.out.wasm:wasm-function[56]:0x2fe4
at http://127.0.0.1:3000/websocket/a.out.wasm:wasm-function[110]:0x5d6d
at http://127.0.0.1:3000/websocket/a.out.wasm:wasm-function[56]:0x2fe4
at http://127.0.0.1:3000/websocket/a.out.wasm:wasm-function[94]:0x524d
at callUserCallback (http://127.0.0.1:3000/websocket/a.out.js:8:18393)
```
The same error happens when I change the order, I place ```printf``` after. It successfully initiated the bridge, but ```printf``` prints empty URL. ```bridgeUrl``` is messed up whenever passed into a function.
Contributor guide
Assessment
This issue has not been assessed yet.