Skip to content

Commit

Permalink
Modify the tcp_server example to support target_os = "wasi"
Browse files Browse the repository at this point in the history
Use the `LISTEN_FDS` mechanism to use pre-opened sockets.

Especially for `wasm32-wasi` there is no other way to get access to sockets,
than to use pre-opened sockets.

Because `wasm32-wasi` does not yet return `TcpListener::local_addr()`, an
unspecified IP address and port will be returned and displayed.

```
$ cargo +nightly build --release --example tcp_server --features="os-poll net"
   Compiling ppv-lite86 v0.2.15
   Compiling getrandom v0.2.3
   Compiling mio v0.8.0 (/home/harald/git/mio)
   Compiling env_logger v0.8.4
   Compiling rand_core v0.6.3
   Compiling rand_chacha v0.3.1
   Compiling rand v0.8.4
    Finished release [optimized] target(s) in 1.75s

$ wasmtime run --tcplisten 127.0.0.1:9000 --env 'LISTEN_FDS=1' target/wasm32-wasi/debug/examples/tcp_server.wasm
```

Signed-off-by: Harald Hoyer <harald@profian.com>
  • Loading branch information
haraldh committed Feb 15, 2022
1 parent 0aa5705 commit c66379a
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions examples/tcp_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,32 @@ fn main() -> io::Result<()> {
let mut events = Events::with_capacity(128);

// Setup the TCP server socket.
let addr = "127.0.0.1:9000".parse().unwrap();
let mut server = TcpListener::bind(addr)?;
let mut server = {
if std::env::var("LISTEN_FDS").is_ok() {
#[cfg(unix)]
use std::os::unix::io::FromRawFd;
#[cfg(target_os = "wasi")]
use std::os::wasi::io::FromRawFd;

let stdlistener = unsafe { std::net::TcpListener::from_raw_fd(3) };
stdlistener.set_nonblocking(true).unwrap();
println!("Using preopened socket FD 3");
println!("You can connect to the server using `nc`:");
match stdlistener.local_addr() {
Ok(a) => println!(" $ nc {} {}", a.ip().to_string(), a.port()),
Err(_) => println!(" $ nc <IP> <PORT>"),
}
println!("You'll see our welcome message and anything you type will be printed here.");
TcpListener::from_std(stdlistener)
} else {
let addr = "127.0.0.1:9000".parse().unwrap();
let listener = TcpListener::bind(addr)?;
println!("You can connect to the server using `nc`:");
println!(" $ nc 127.0.0.1 9000");
println!("You'll see our welcome message and anything you type will be printed here.");
listener
}
};

// Register the server with poll we can receive events for it.
poll.registry()
Expand All @@ -34,10 +58,6 @@ fn main() -> io::Result<()> {
// Unique token for each incoming connection.
let mut unique_token = Token(SERVER.0 + 1);

println!("You can connect to the server using `nc`:");
println!(" $ nc 127.0.0.1 9000");
println!("You'll see our welcome message and anything you type will be printed here.");

loop {
poll.poll(&mut events, None)?;

Expand Down Expand Up @@ -65,11 +85,8 @@ fn main() -> io::Result<()> {
println!("Accepted connection from: {}", address);

let token = next(&mut unique_token);
poll.registry().register(
&mut connection,
token,
Interest::READABLE.add(Interest::WRITABLE),
)?;
poll.registry()
.register(&mut connection, token, Interest::WRITABLE)?;

connections.insert(token, connection);
},
Expand Down

0 comments on commit c66379a

Please sign in to comment.