Skip to content

WebSocket Timeout and IronError with Undefined Details in ironrdp-web When Connecting to RDP Server #767

@hasanodabasi

Description

@hasanodabasi

I am encountering an issue with the ironrdp-web module when attempting to establish an RDP connection to a Windows Server 2022 RDP server using the WebAssembly (WASM) client. The connection process consistently fails with a WebSocket timeout after approximately 2 minutes, followed by an IronError with undefined kind and backtrace details.

Steps to Reproduce
Setup:
Environment: Windows Server 2022 (RDP server at :).
Proxy: A Node.js WebSocket-to-TCP proxy (proxy.js) running on ws://:, forwarding to localhost:.
Client: ironrdp-web WASM module built with wasm-pack build --target web (using wasm-bindgen v0.2.87).
Code: A JavaScript client using SessionBuilder.init() to configure the RDP connection, as shown below:
html

<title>IronRDP WASM RDP Client</title> <style> html, body { margin: 0; height: 100%; overflow: hidden; background: #000; } #rdpCanvas { width: 100%; height: 100%; display: block; border: 1px solid red; } </style>
Close Application
<script type="module"> import init, * as IronRdp from "./pkg/ironrdp_web.js"; function setCursorStyle(style) { const canvas = document.getElementById("rdpCanvas"); switch (style) { case 0: canvas.style.cursor = "default"; break; case 1: canvas.style.cursor = "pointer"; break; case 2: canvas.style.cursor = "text"; break; default: canvas.style.cursor = "auto"; } console.log("Cursor style set:", style); } async function startRdp() { try { await init(); console.log("IronRDP WASM module loaded."); const ws = new WebSocket("ws://:"); ws.binaryType = "arraybuffer"; ws.onopen = () => console.log("WebSocket connection established."); ws.onerror = (error) => console.error("WebSocket connection error:", error); ws.onclose = (event) => console.log("WebSocket connection closed:", event.code, event.reason); ws.onmessage = (event) => { console.log("WebSocket data received, time:", new Date().toISOString()); if (event.data instanceof ArrayBuffer) { console.log("Data size:", event.data.byteLength); console.log("Data content (first 10 bytes):", new Uint8Array(event.data).slice(0, 10)); } else { console.log("Data type:", typeof event.data, "Content:", event.data); } }; const canvas = document.getElementById("rdpCanvas"); const cursorContext = null; const builder = IronRdp.SessionBuilder.init() .username("\\") .password("") .destination("") .auth_token("") .render_canvas(canvas) .set_cursor_style_callback(setCursorStyle) .set_cursor_style_callback_context(cursorContext) .proxy_address("ws://:"); console.log("SessionBuilder configuration completed:", builder); const session = await builder.connect(); console.log("RDP session started."); session.run().then(terminationInfo => { console.log("Session terminated:", terminationInfo.reason()); }).catch(error => { console.error("Error running session:", error); }); canvas.width = 1280; canvas.height = 720; const ctx = canvas.getContext("2d"); if (ctx) { console.log("Canvas size:", canvas.width, "x", canvas.height); ctx.fillStyle = "blue"; ctx.fillRect(0, 0, 100, 100); } document.getElementById("closeBtn").onclick = () => { if (confirm("Are you sure you want to close the application?")) { session.shutdown(); } }; } catch (error) { console.error("Connection error:", error); console.error("Error type:", error.kind ? error.kind() : "Unknown"); console.error("Error details:", error.backtrace ? error.backtrace() : "Unknown"); } } startRdp(); </script> Run the Test: Start the proxy: node proxy.js (listening on ws://:). Serve the client: http-server -p . Open http://: in a browser (Chrome 135). Observed Behavior The client logs show: text

IronRDP WASM module loaded.
SessionBuilder configuration completed: SessionBuilder {__wbg_ptr: 1770504}
After approximately 2 minutes, the following errors appear:
text

WebSocket connection to 'ws://:/' failed:
WebSocket connection error: Event {isTrusted: true, type: 'error', ...}
WebSocket connection closed: 1006
Connection error: IronError {__wbg_ptr: 1769688}
Error type: undefined
Error details: undefined
Proxy logs (from a previous run):
text

Proxy portunda çalışıyor
WebSocket istemcisi bağlandı
RDP sunucusuna bağlandı
WebSocket’ten veri alındı, boyutu: 97
RDP hatası: Error: read ECONNRESET
WebSocket istemcisi ayrıldı
qwinsta output: No session is visible, indicating the connection does not reach the authentication stage.
Expected Behavior
The WebSocket connection should establish successfully, and the RDP session should proceed to authentication, creating a session visible in qwinsta.
Analysis
The 2-minute delay suggests a timeout in the connect method, likely in the WebSocket state polling loop in session.rs:
rust

loop {
match ws.state() {
websocket::State::Connecting => {
trace!("WebSocket is connecting to proxy at {proxy_address}...");
gloo_timers::future::sleep(Duration::from_millis(50)).await;
}
...
}
}
The IronError lacks kind and backtrace details, indicating a potential issue with wasm_bindgen bindings for the IronError struct.
The ECONNRESET error in the proxy suggests the RDP server (Windows Server 2022) is rejecting the connection, possibly due to:
Incorrect credentials (<username>, ).
Protocol incompatibility (e.g., RDCleanPath or CredSSP issues).
Server configuration (e.g., Network Level Authentication (NLA) or TLS requirements).
The WebSocket closure with code 1006 indicates an abnormal disconnection, likely due to the proxy or server not responding as expected.
Environment
OS: Windows Server 2022
Browser: Chrome 135
IronRDP: Latest commit from the main branch (as of April 2025)
wasm-bindgen: 0.2.87 (set in ironrdp-web/Cargo.toml, but cargo tree shows 0.2.100 due to dependency conflicts)
wasm-pack: 0.12.1
Node.js: Proxy running with node proxy.js
Additional Notes
Using SessionBuilder.init() resolved previous null pointer passed to rust errors for string parameters (username, password, etc.).
A test function (test_string_binding) added to src/lib.rs confirmed that wasm_bindgen string bindings work correctly outside of SessionBuilder.
Dependency conflict with wasm-bindgen v0.2.100 persists, despite setting 0.2.87 in [workspace.dependencies].
Questions for Maintainers
Is there a known issue with the connect method in ironrdp-web causing WebSocket timeouts when connecting to Windows Server 2022?
Could the IronError binding issue (undefined kind and backtrace) be related to wasm_bindgen configuration or the export! macro in iron_remote_desktop?
Are there specific server configurations (e.g., NLA, TLS, CredSSP) required for ironrdp-web to connect to Windows Server 2022?
Any recommendations for resolving the wasm-bindgen version conflict (v0.2.100 overriding 0.2.87)?
Logs and Files
Console Logs: Attached above.
Proxy Logs: Attached above (from a previous run).
qwinsta Output: No session visible.
Cargo.toml (relevant parts):
toml

ironrdp-web/Cargo.toml

[dependencies]
wasm-bindgen = "0.2.87"
...

IronRDP/Cargo.toml

[workspace.dependencies]
wasm-bindgen = "0.2.87"
cargo tree (partial):
text

├── wasm-bindgen v0.2.100
├── wasm-bindgen-futures v0.4.50
...
Request
Could you please provide guidance on debugging the WebSocket timeout and IronError issues? Specifically, any insights into the connect method’s behavior, IronError binding issues, or server configuration requirements would be greatly appreciated. I can provide additional logs or test specific scenarios if needed.

Thank you for your support!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions