Ruby on Railsで簡単にMessagePackエコーサーバを構築してみた話 - Unity通信の学習用に

# はじめに
Unityのタグを入れましたが、内容はRailsを使ったサーバ構築の話です。
Railsを使ったサーバの構築がすごく手軽で感動したので記事として残しました。

### なぜエコーサーバを立てようと思ったのか
Unityの通信周りの実装を学ぼうと思い、通信テストを効率的に行うためにはサーバが必要になりました。
「エコーサーバ」という、クライアントから送信されたデータをそのまま返すサーバを立てることで、クライアント側の実装を容易にテストできるようになります。
エコーサーバとは、クライアントから受け取ったリクエストデータをそのままレスポンスとして返すシンプルなサーバです。
これにより、クライアントが送信するデータと受信するデータを簡単に確認でき、テストが非常に効率的になります。

### MessagePackについて
通信のデータ形式としてMessagePackを使用します。
JSONが広く使われていますが、MessagePackはパフォーマンス面で優れており選択肢として選ばれるケースも増えると思います。
私自身がMessagePackを試してみたいという好奇心から始めた内容となります。

### この記事を読むことで得られる事
Ruby on Railsを使ってエコーサーバを構築する手順を紹介します。
この記事を読むことで、Ruby on Railsを使ってエコーサーバを構築する手順を理解できるようになります。


# 開発環境 について
この記事ではRuby on Railsが既にインストールされている前提で進めます。
Railsの環境が整っていない場合は、Ruby on Rails チュートリアルを参考にしてください。
https://railstutorial.jp/chapters/beginning?version=7.0#cha-beginning

### 開発環境
```
	•	OS: macOS Sonoma バージョン14.5
	•	Rails: 7.0.8.4
	•	Ruby: 3.2.5 (2024-07-26 revision 31d0f1a2e7) [arm64-darwin23]
	•	Bundler: 2.5.17
 ```


# 手順
## 1. Ruby on Railsプロジェクトの作成
まず、APIモードのRailsプロジェクトを作成します。
今回は「UnityServer」という名前にしました。
ターミナルを起動して、プロジェクトを作成したいフォルダにカレントディレクトリを合わせ、以下を実行します。
``` bash
rails new UnityServer --api
```
RailsのAPIモードは、ビューやアセットの機能を省略し、APIの開発に特化した軽量なプロジェクトを生成します。今回はUnityからの通信APIを作成することを目的としているため、このモードを選択しました。


## 2. MessagePackのサポートを追加
次に、MessagePackのサポートを追加します。Gemfileに以下の行を追加します。
``` ruby
gem 'msgpack'
```
追記したら、ターミナルに戻り以下を実行します
``` bash
bundle install
```

## 3. Railsルートとコントローラーの設定
APIのエンドポイントを定義するため、config/routes.rbを以下のように編集します。今回はcommunicationsという名前のコントローラーを使用します。
(名前に意味はなくAIにお勧めされました）
``` ruby
Rails.application.routes.draw do
  post 'login', to: 'communications#login'
  post 'card', to: 'communications#card'
  post 'title', to: 'communications#title'
end
```
この設定により、
`http://localhost:3000/login`や`http://localhost:3000/card`などのURLでAPIがルーティングされ、コントローラー側でリクエストを受け取れるようになります。
#### コードのポイント

	•	routes.rb: ここでエンドポイントを定義し、特定のURLにリクエストが来たときに、どのコントローラーのどのアクションが呼ばれるかを指定します。
	•	コントローラー: コントローラーは、受け取ったリクエストに応じてアクション（処理）を実行し、結果をレスポンスとして返します。

## 4. コントローラーの作成と実装
次に、app/controllers/communications_controller.rbファイルを作成し、以下のように実装します。
``` ruby
class CommunicationsController < ApplicationController
  require 'msgpack'

  before_action :unpack_data

  def login
    process_data
  end

  def card
    process_data
  end

  def title
    process_data
  end

  private

  def unpack_data
    @data = MessagePack.unpack(request.body.read)
  end

  def process_data
    # ここで@dataに対する任意の処理を行う
    Rails.logger.info("process_data: #{@data.to_msgpack}")
    render plain: @data.to_msgpack
  end
end
```
### コードの流れ
```
before_action :unpack_data: リクエストがコントローラーのアクションに到達する前に、リクエストボディをMessagePack形式でアンパックして、データを@dataに格納します。
process_data: 各アクションが完了した後に、@dataをMessagePack形式で再パックし、レスポンスとしてクライアントに返す共通処理です。
各APIで独自の処理を行う場合はprocess_data前に行うイメージです。
 ```


## 5. Railsサーバーの起動と動作確認

最後に、ターミナルでプロジェクトのディレクトリに移動し、以下のコマンドでサーバーを起動します。
``` bash
rails server
```
これで、ローカル環境で`http://localhost:3000/login`や`http://localhost:3000/card`などにアクセスして、エコーサーバが動作しているか確認できます。

## 6. Unityクライアントでのテスト
サーバが正常に動作しているか確認するためには、クライアントからリクエストを送信してテストする必要があります。
私の場合、curlでのテストを試みましたが、MessagePackの処理がうまく動作しなかったため、Unityのクライアントコードを用いてテストを行い正常に動作していることを確認しました。

### Unityでのクライアント実装
Unity側のクライアント通信処理については、別途記事をまとめる予定です。Unityからのリクエストとサーバーの応答を確認し、実際にどのように通信が行われるかを詳細に説明しますので、そちらもぜひご覧ください。

### サーバにデプロイして使う場合
Ruby on Rails チュートリアル　の手順に沿ってデプロイすることで、動作を確認できました。
APIモードで作ったプロジェクトなので、Renderでデプロイする場合はデフォルトで設定される`Build Command`だといらないコマンドがありエラーが発生しました。
```
bundle install;
```
だけにするとデプロイに成功しました。




# まとめ

今回、Ruby on Railsを使ってエコーサーバを立てる手順を紹介しました。
特にMessagePackを使用したデータのシリアライズとデシリアライズの実装が簡単にできることがわかりました。
クライアントの挙動を確認するためのテストサーバとして、非常に簡単にセットアップできることがわかりました。

エコーサーバの構築は、クライアントの通信処理を学ぶ上で非常に有効です。今回紹介した手順を参考に、ぜひ自身のプロジェクトでも活用してみてください。

#### 他の選択肢について
もちろん、他の言語やフレームワークでもエコーサーバを立てることは可能です。
例えば、Node.jsやPythonを使って同様のサーバを構築することもできます。
しかし、Railsの魅力は、その簡便さと生産性の高さにあります。
特に今回のようなシンプルなAPIを作成する場合、Railsは非常に適した選択肢だと感じました。