こんにちは。バックエンドエンジニアの米山です。
今回開発案件で、WebSocketを使ったシステム開発に携わることになったので、導入時のメモや困ったことetc...を書いていこうと思います。
まず、WebSocketとは?
Socketを使った技術は、古くからJavaなどの世界で存在していましたが、WebSocketはこれをインターネット上で可能にしたものです。
【従来のWeb通信】
従来のWeb通信は「1回のリクエスト」に「1回のレスポンス」で処理を行なっていました。
キャッチボールをイメージしてもらえたら良いと思います。
【WebSocketによる通信】
これがWebSocketになると「双方向通信」となり、ソケットが開いている間は任意のタイミングでクライアント<-->サーバ間通信が行えます。
WebSocketを導入するために
今回実施した開発案件では、以下の環境・条件で構成を考えました。
- サーバ側の開発言語はPHP(Laravel)であること
- フロントエンド側にサーバ側の言語仕様を押し付けないこと
- PHP(Laravel)の設計思想や概念に依存するコードをフロント側に強要しない。フロントはフロントで技術選定できる環境にする。
- なるべく、サードパーティ製のツール(firebase等)を使わず、リアルタイム性を実現できること
以上のことから、今回は「Ratchet」というライブラリを選択しました。
LaravelでWebSocketを構築しようとすると、必ずと言っていいほど「Laravel-Echo」が検索ヒットします。
しかし上記に挙げた条件の通り、フロントエンドはフロントエンドで技術選定を行いコーディングするので、依存しないRatchetを選びました。
早速Ratchetを導入!
では、LaravelプロジェクトにRatchetを導入してみましょう。
LaravelではComposerを使ったライブラリ管理が可能ですが、Ratchetの公式ページに導入方法が記載されています。
ComposerでRatchetをインストール
公式ページに書いている通り、composer.jsonを書き換えても良いですし
composer require cboden/ratchet
でも良いです。(執筆時点でのVer.はv0.4.3を使用しています)
WebSocketサーバを作る
Webサーバ内で別のサーバが動くイメージで実装します。
Webサーバ(apache)内でアプリサーバ(tomcat)が動く感覚に近いです。
Java使いはイメージしやすいかも。(厳密には異なる概念です。あくまでイメージね)
require 'vendor/autoload.php'; $app = require 'bootstrap/app.php'; $app->make(Kernel::class)->bootstrap(); $server = IoServer::factory( new HttpServer( new WsServer( new Chat() ) ), 8282 ); $server->run();
ここでは、Laravelのメソッドや環境変数等を使うために「require 'vendor/autoload.php'」したり色々やっています。
これを自作artisanコマンド等で、自動実行できるようにするとこの記述は不要になります。
Laravel上で動くようになるからですね。
コードを見ておや?と思った方がいるかもしれません。
WebSocketはHTTP技術を拡張したものなので、HttpServerクラスでListenを行います。
このHttpServerクラスはRatchetで作られたものですが、RequestオブジェクトはPSR-7 HTTP message interfacesで拾うことができます。
従って、その引数に渡しているWsServerインスタンスやChatインスタンスも同様です。
Chatクラスの中身は、公式ページにも記載がある通りMessageComponentInterfaceを実装する形にします。
これを実装することでWebSocketの各イベントが使用可能になります。
今回、私が実装したのは以下の4つです。
- onOpen() : クライアントから初めてWebSocketに接続された時に発火するイベント
- onMessage() : クライアントのsend()時に発火するイベント。クライアントにメッセージを返すところまでここで実装する。
- onClose() : クライアントから切断(close()時、もしくはブラウザの×ボタン押した時)に発火するイベント
- onError() : WebSocket通信中に何らかのエラーが発生した時に発火するイベント
まとめ
LaravelでRatchetを扱う時は
- Composerでライブラリをインストール
- ListenするWebSocketサーバ(クラス)を作る
- 各イベントを理解する
をわかっていれば実装できると思います。
まだまだ資料は少なめですが、Ratchet関連の解説記事もそこそこあるので、調べたらいくつか出てきます。
今回はここまでです。良きSocketライフを!(笑)
Wizではエンジニアを募集しております。
興味のある方、ぜひご覧下さい。