Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

エコーサーバーを作ろう

エコーサーバーは素早く直感的に作ることができます。

システムを定義する

// 頻繁に使用されるものが詰まってます
use ecson::prelude::*;

fn echo_system(
    mut messages: MessageReader<MessageReceived>,
    mut outbound: MessageWriter<SendMessage>,
) {
    for message in messages.read() {
        outbound.write(SendMessage {
            target: message.entity,
            payload: message.payload.clone(),
        });
    }
}

引数

  1. mut messages: MessageReader<MessageReceived>:
    受け取ったメッセージ(MessageReceived)を読み取ります(MessageReader)。
    MessageReaderは内部にカーソルを持つことで「どこまで読んだか」を更新するため、mutを付けましょう。
  2. mut outbound: MessageWriter<SendMessage>:
    送るメッセージ(SendMessage)を書き込みます(MessageWriter)。

ロジック

for message in messages.read() {

}

ev_receivedMessageReaderなので.read()が使えます。.read()は、Messagesという保管庫内のMessageReaderが未読のメッセージを順に処理します。中身(この場合MessageReceived)を参照で順番に返します。

outbound.write(SendMessage {
   target: message.entity,
   payload: message.payload.clone(),
});

outboundMessageWriterなので.write()が使えます。.write()は、Messagesという保管庫に引数に渡されたラベルを貼って書き込んでいきます。 この場合SendMessageという構造体を渡していますが、フィールドのtargetは送信したい相手、payloadは内容を入れます。

まとめ

つまり、

  1. MessageReaderで受信したメッセージを読み取り、
  2. そのメッセージの情報をもとにSendMessageを作り、
  3. MessageWriterでそれを返しています。

アプリを初期化してシステムを登録しよう

fn main() {
    EcsonApp::new()
        .add_plugins(EcsonWebSocketPlugin::new("127.0.0.1:8080"))
        .add_systems(Update, echo_system)
        .run();
}

上から見ていきましょう。

  1. EcsonApp::new()
    EcsonAppインスタンスを作ります。これがECSやネットワーク等すべてを統括しています。
  2. .add_plugins(EcsonWebSocketPlugin::new("127.0.0.1:8080"))
    .add_pluginsでプラグインを登録します。EcsonWebSocketPluginはWebSocketサーバーをEcsonに統合します。::new("127.0.0.1:8080")によってアドレスを127.0.0.1:8080で起動しています。
  3. .add_systems(Update, echo_system)
    add_systemsでシステム(ロジック)を登録します。第一引数にはスケジュールを、第二引数にはシステムを渡します。Updateは可能な限り毎フレーム実行します。
  4. .run();
    実行!

フロントエンドからテストをしよう

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>echoテスト</title>
</head>
<body>
    <h1>Ecson Echo Test</h1>
    <input type="text" id="msgInput" placeholder="メッセージを入力">
    <button onclick="sendMessage()">送信</button>
    <ul id="log"></ul>

    <script>
        const ws = new WebSocket('ws://127.0.0.1:8080');
        const log = document.getElementById('log');

        ws.onopen = () => log.innerHTML += '<li>✅ 接続成功</li>';
        
        ws.onmessage = (event) => {
            log.innerHTML += `<li>📩 サーバーから: ${event.data}</li>`;
        };

        function sendMessage() {
            const input = document.getElementById('msgInput');
            ws.send(input.value);
            log.innerHTML += `<li>📤 送信: ${input.value}</li>`;
            input.value = '';
        }
    </script>
</body>
</html>

サーバーを起動し、HTMLにアクセスします。

cargo run --release # 任意

alt text

お疲れ様でした! 次回は接続者全員に対してメッセージを送信します。