Possible to connect to `TcpListener` through WASM?

I'm creating a multiplayer game, and I'm sending information through serialized JSON over TCP.

My client just looks like this:

use std::net::TcpStream;

fn main() {
    let stream = TcpStream::connect("127.0.0.1:19773").unwrap();
}

My server looks like this:

use std::net::TcpListener;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:19773").unwrap();
}

This sadly doesn't work in WASM. The client returns an error saying that the operation isn't permitted on this platform.

Is there any way to fix this?

1 Like

WASM programs can run in two types of environments:

  1. The web browser (e.g. Firefox, Chrome, Safari, Edge)
  2. A server-side runtime (e.g. WasmEdge, Wasmtime, Wasmer, WAMR)

If you are running on the web (type 1), you can't open raw TCP connections for security reasons. The closest thing is WebSockets, or you can use some kind of HTTP-based protocol to communicate with the server. Both options require your game server to understand some higher-level protocol than raw TCP.

An example of connecting to a server from browser WASM using WebSockets:
https://rustwasm.github.io/wasm-bindgen/examples/websockets.html

If you are running your game client as part of a desktop app, then what you want may be possible. I haven't tested this works, but WasmEdge claims to support opening a TCP client connection:

1 Like

I was planning to run it in the browser. That's a shame, as I didn't want to use HTTP, as I have other clients that won't be running in the web and it would be unnecessary. I guess I could just send my JSON through HTTP requests then? Would I be using something like Actix or Rocket?

On the server-side, yes. You could either have a separate web server proxying requests to your TCP-based game server, or have one server program open two network ports (one for HTTP/WebSockets and the other for raw TCP).

1 Like