WebAssembly (WASM) and WebAssembly System Interface (WASI) are opening new opportunities for developers. .NET developers became familiar with WASM when Blazor WebAssembly was released. Blazor WebAssembly runs client-side in the browser on a WebAssembly-based .NET runtime. WASI is bringing WASM out of the browser world by providing a system interface to run WebAssembly outside the web. It is a standard for how WASM modules interact with the host environment. This post will show you how to run .NET 7 on a Raspberry PI Zero 2 W using WASM and WASI.
What is WASM?
WebAssembly (WASM) is a binary instruction format for a stack-based virtual machine. WASM is a portable compilation target for programming languages. It is a low-level assembly-like language with a compact binary format that runs near-native performance and provides languages such as C#, C/C++, and Rust… with a compilation target that can run in browsers and other environments.
What is WASI?
WebAssembly System Interface (WASI) is a standard for how WASM modules can interact with the host environment. WASI is a specification for a system interface for WebAssembly. It is a set of APIs that a WebAssembly module can call to access the host environment.
As WASI is about running securely WASM outside the browser, it cannot leverage the runtime embedded in our modern web browsers. It needs another runtime. It is why runtimes like Wasmtime, Wasmer or WasmEdge exist. Wasmtime is a standalone JIT-style runtime for WebAssembly. It is designed to run as a standalone command-line utility, embedded into other applications, or used to run WebAssembly modules within larger’s runtimes.
.NET 7 WASI SDK
Steve Sanderson is known as the creator of ASP.NET Core Blazor WebAssembly and opened the GitHub repository SteveSandersonMS / dotnet-wasi-sdk some months ago. The “Experimental WASI SDK for .NET Core” was born. A couple of weeks ago, the experiment moved to dotnet / dotnet-wasi-sdk. Is it a hint that it is ready to move to the next step? I am convinced and hope we will hear about this during the .NET Conf 2022.
Creating a .NET WASI project
The goal is to build a .NET 7 Web Api using WASI SDK for .NET and to run it on a Raspberry PI Zero 2 W using Wasmtime. I won’t repeat the instructions here. The only difference is that I am using ASP.NET Core Web API project template and not the Web template.
So, the following command will create a .NET 7 Web API project then you add WASI SDK for .NET as described on “How to use: ASP.NET Core applications“ page.
1 | dotnet new webapi -o WasiWebApi |
Building the .NET WASI project
The following command will build and publish the .NET 7 Web API project for WASI.
1 | dotnet publish -c Release |
You end up with a WasiWebApi.wasm
file in the WasiWebApi\bin\Release\net7.0\
folder, which is the WebAssembly module that you can run on Wasmtime.
Running the .NET WASI project locally on Windows using Wasmtime
Download Wasmtime from the releases GitHub page, e.g. wasmtime-v2.0.1-x86_64-windows.zip. Unzip the archive and add the wasmtime.exe
to your PATH
environment variable.
Then, you can run the WebAssembly module using the following command.
1 | wasmtime bin\Release\net7.0\WasiWebApi.wasm --tcplisten localhost:8080 --env ASPNETCORE_URLS=http://localhost:8080 |
or you can use the run
command.
1 | dotnet run |
Then you can access the Web API using the following URL: http://localhost:8080/weatherforecast.
Uploading the project to the Raspberry PI Zero 2 W
Today, Windows supports ssh and scp out of the box. It is super easy to copy our application from our PC to the Raspberry PI Zero 2 W. In this example, my PI Zero 2 W is named piw.lan
and I am using the default user pi
to copy the wasm file, to the folder /home/pi/wasm.
1 | scp .\bin\Release\net7.0\WasiWebApi.wasm pi@piw.lan:/home/pi/wasm |
Running the .NET WASI project on Pi Zero 2 W using Wasmtime
Connect to your Raspberry PI Zero 2 W using ssh.
1 | ssh pi@piw.lan |
We first need to install Wasmtime on the Raspberry PI Zero 2 W. We need again to download Wasmtime from the releases GitHub page, but this time for Linux 64 bits e.g. wasmtime-v2.0.1-aarch64-linux.tar.xz. Unzip the archive and copy the wasmtime
file to the folder /home/pi/wasm.
1 | wget https://github.com/bytecodealliance/wasmtime/releases/download/v2.0.1/wasmtime-v2.0.1-aarch64-linux.tar.xz |
The following command will run the project using Wasmtime.
1 | ./wasmtime WasiWebApi.wasm --tcplisten piw.lan:5000 --env ASPNETCORE_URLS=http://piw.lan:5000 |
Then you can access the Web API using the following URL: http://piw.lan:5000/weatherforecast and should see something like this
Conclusion
We have seen that it is possible to run the same Wasm module built from a .NET 7 Web API on Windows and then on a Raspberry PI Zero 2 W using WASI SDK for .NET and Wasmtime. It was a very interesting experiment. I am looking forward to seeing what will happen next. I hope we hear about this during the .NET Conf 2022.