1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

wRPCはWITを用いたRPC

Posted at

wRPC はインターフェース定義に WIT1を用いた RPC 技術で、通信プロトコルは現時点で TCP, UNIXドメインソケット, QUIC, NATS に対応しているようです。

WebAssembly に特化したものではなく、今のところ次のような使い方があります。

実装方法 実行方法
a WebAssemblyコンポーネント wRPC対応ランタイムによる実行
b ネイティブwRPCアプリケーション(RustやGoで実装) 直接実行

a は通信プロトコル部分をランタイムが適用し、b は通信プロトコル部分も実装するようです。

ここでは wrpc v0.14.0 を使って a の方法を試してみました。

インストール

下記のようにインストールする事で wRPC 対応ランタイムの wrpc-wasmtime コマンドが使えるようになります。

インストール例
$ cargo install wrpc

WebAssembly コンポーネント作成

wRPC のサーバー側とクライアント側の WebAssembly コンポーネントをそれぞれ作成します。

名前はとりあえず serverclient にしました。

サーバー側

まずは WIT を定義します。
add 関数を wRPC で呼び出すように export します。

wit/world.wit
package local:sample;

interface handler {
    add: func(a: s32, b: s32) -> s32;
}

world server {
    export handler;
}

この WIT に基づいた WebAssembly コンポーネントを wit-bindgen で実装しました。

src/lib.rs
mod bindings {
    use crate::Handler;

    wit_bindgen::generate!({
        with: {
            "local:sample/handler": generate,
        }
    });

    export!(Handler);
}

struct Handler;

impl bindings::exports::local::sample::handler::Guest for Handler {
    fn add(a: i32, b: i32) -> i32 {
        a + b
    }
}

Cargo.toml は次のような内容となっています。

Cargo.toml
[package]
name = "server"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
wit-bindgen = "0.35"

ビルド

WASI は使っていないので、ここでは wasm32-unknown-unknown でビルドします。

ビルド例
$ cargo build --release --target wasm32-unknown-unknown

なお、wasm32-wasip2 でビルドしても問題はありません。

クライアント側

クライアント側の WIT では add 関数を import します。

wit/world.wit
package local:sample;

interface handler {
    add: func(a: s32, b: s32) -> s32;
}

world client {
    import handler;
}

add 関数を呼び出して結果を出力するだけの処理を実装してみました。

/src/main.rs
mod bindings {
    wit_bindgen::generate!({
        with: {
            "local:sample/handler": generate,
        }
    });
}

fn main() {
    let a = 2;
    let b = 3;

    let r = bindings::local::sample::handler::add(a, b);

    println!("{a} + {b} = {r}");
}
Cargo.toml
[package]
name = "client"
version = "0.1.0"
edition = "2021"

[dependencies]
wit-bindgen = "0.35"

ビルド

println! 等の使用有無に関わらず、クライアント側は WASI が必要そうなので2wasm32-wasip2 でビルドします。

ビルド例
$ cargo build --release --target wasm32-wasip2

動作確認

通信プロトコルは TCP で実行してみます。

まずは、wrpc-wasmtime tcp serve コマンドでサーバー側を実行しておきます。

server実行
$ wrpc-wasmtime tcp serve ./target/wasm32-unknown-unknown/release/server.wasm
 INFO wrpc_wasmtime_cli: serving instance function name="add"

wrpc-wasmtime tcp run コマンドでクライアント側を実行するとこのような結果となりました。

client実行
$ wrpc-wasmtime tcp run ./target/wasm32-wasip2/release/client.wasm
2 + 3 = 5
  1. Wasm Interface Type

  2. wasm32-unknown-unknown でビルドした結果を wrpc-wasmtime run で実行してみたところエラーが発生した

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?