グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



WebSocketライブラリを使用して、シンプルなリアルタイム通知アプリを作成する方法

ふと、リアルタイム通信ってどうやって行っているのだろうと気になってしまいました。

リアルタイム通信の仕組みを理解するために、今回はWebSocketライブラリを使用して簡単なアプリケーションを作成してみます。

前提

  • Ubuntu 22.04
  • PHP 8.1.2
  • CodeIgniter 4.5.1

WebSocketとは

WebSocketは、サーバーとクライアント(ブラウザなど)の間でリアルタイムの双方向通信を可能にする技術です。
また、WebSocketライブラリは、WebSocket通信を簡単に実現するためのツールです。

普通のwebページは、HTTP通信を使ってデータをやり取りしています。この場合、クライアントがサーバーにリクエストを送るたびに、サーバーが応答します。つまり、クライアントが「ください」と言わない限り、サーバーは何もしません。

一方で、WebSocketは仕組みが少し異なります。最初にクライアントがサーバーに接続を確立すると、通信チャンネルが開いたままになります。この状態では、クライアントがリクエストを送らなくても、サーバー側が好きなタイミングでデータを送信できます。
これにより、例えば以下のようなことが可能になります

  • サーバーが何か新しい情報を受け取ったら、それをすぐクライアントに通知。
  • クライアント側が常に最新の情報をリアルタイムで受け取れる。

簡単に言うと、WebSocketは「常につながっている電話回線」のようなもので、クライアントとサーバーが自由にデータを送り合える仕組みです。

参考:WebSocket 入門

実際にシンプルなリアルタイム通知アプリを作成してみよう

1. CodeIgniter 4のセットアップ

CodeIgniter4の環境がまだ用意されていない場合は、前回の「ランダムユーザー生成」の記事と同様に、

ばねさんの「CodeIgniter4のインストール」を参考に、環境を構築してください。

2. Ratchetのインストール

次に、WebSocketライブラリ「Ratchet」をインストールします。

composer require cboden/ratchet

3. WebSocketサーバーを実装

WebSocketサーバーを作成するために、以下のコードを app/Libraries/NotificationServer.php に保存します。

<?php

namespace App\Libraries;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class NotificationServer implements MessageComponentInterface
{
    protected $clients;

    public function __construct()
    {
        $this->clients = new \SplObjectStorage();
    }

    public function onOpen(ConnectionInterface $conn)
    {
        $this->clients->attach($conn);
        echo "新しい接続: {$conn->resourceId}\n";
    }

    public function onMessage(ConnectionInterface $from, $msg)
    {
        echo "メッセージを受信しました: {$msg}\n";

        foreach ($this->clients as $client) {
            $client->send($msg);
            echo "メッセージを送信しました: {$msg}\n";
        }
    }

    public function onClose(ConnectionInterface $conn)
    {
        $this->clients->detach($conn);
        echo "切断された接続: {$conn->resourceId}\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
        echo "エラー: {$e->getMessage()}\n";
        $conn->close();
    }
}

ここでは、

  • onOpenメソッドで新しい接続を受け入れる
  • onMessageメソッドでクライアントから受け取ったメッセージを全てのクライアントに送信する
  • onCloseメソッドで切断されたクライアントを管理リストから削除する

という動作をしています。

4. ルートの設定

通知ページを表示するために、以下のルートを app/Config/Routes.php に保存します。

$routes->get('/notifications', 'NotificationController::index');

5. 通知ページを表示するコントローラーを実装

通知ページを表示するためのコントローラーを作成するために、以下のコードを app/Controllers/NotificationController.php に保存します。

<?php

namespace App\Controllers;

class NotificationController extends BaseController
{
    public function index()
    {
        return view('notifications');
    }
}

6. 通知ページの実装

ブラウザで通知を表示するためのHTMLを作成するために、以下のコードを app/Views/notifications.php に保存します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>リアルタイム通知</title>
</head>
<body>
    <h1>リアルタイム通知</h1>
    <div id="notifications"></div>
    <button onclick="sendNotification('新しい通知です!')">通知を送信</button>

    <script>
        const socket = new WebSocket("ws://localhost:8081/notifications");

        socket.onmessage = function(event) {
            const notification = event.data;
            document.getElementById("notifications").innerHTML += `<p>${notification}</p>`;
        };

        function sendNotification(message) {
            socket.send(message);
        }
    </script>
</body>
</html>

7. WebSocketサーバーの起動

以下のコマンドでWebSocketサーバーを起動します。

php spark socket:start

8. HTTPサーバーの起動

別のターミナルで以下を実行してCodeIgniterのサーバーを起動します。

php spark serve --port=8080

アプリケーションの実行

アプリケーションを実行して、「通知を送信」を押下し、通知がリアルタイムで画面に表示されるか試してみます。

のように、通知がリアルタイムで画面に表示されることを確認できました。

また、WebSocketサーバーでは

WebSocketサーバーを起動中...
新しい接続: 196
メッセージを受信しました: 新しい通知です!
メッセージを送信しました: 新しい通知です!

のように表示されていれば、正常にサーバー側で通知が送信され、全てのクライアントで通知が表示されています。

さいごに

今回は、CodeIgniter 4とRatchetを使用して、シンプルなリアルタイム通知アプリを構築しました。
この仕組みを基に、チャットシステムやリアルタイム更新機能を作成することも可能です。
WebSocketライブラリはたくさん種類があるので、ご自身の開発環境に合うものをお選びいただければと思います。

この記事が皆さんのPHPとWebSocketの理解を深める一助となれば幸いです。

この記事を書いた人

チェリー
チェリー
モノを売るより創りたいという想いで、約5カ月間の独学期間を経て、営業職からエンジニアへ転職。現在は、ソリューション事業部のWebエンジニアとして、主にシステムの開発・運用に従事している。趣味は料理と釣り。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします