ホームページ >バックエンド開発 >PHPチュートリアル >PHP と WebSocket を使用してリアルタイム コラボレーション ツールを開発する方法

PHP と WebSocket を使用してリアルタイム コラボレーション ツールを開発する方法

PHPz
PHPzオリジナル
2023-12-17 22:40:03865ブラウズ

PHP と WebSocket を使用してリアルタイム コラボレーション ツールを開発する方法

インターネットとモバイル デバイスの普及に伴い、作業効率を向上させるためのリアルタイム コラボレーション ツールの必要性が高まっています。このような背景から、インスタント メッセージングやリアルタイム コラボレーション ツールの共同編集などの機能の要件がますます一般的になってきています。この記事では、PHP と WebSocket を利用してリアルタイムの Web ベースのコラボレーション ツールを実装する方法を紹介します。関連するコード例も提供されます。

WebSocket の概要

WebSocket は新しいタイプの Web 通信プロトコルで、HTTP プロトコルではなく TCP プロトコルに基づいており、双方向通信機能を提供します。 Ajax ポーリング技術と比較して、WebSocket はリアルタイム性が高く、通信効率が高いという利点があります。

これに先立って、リアルタイムでブラウザにデータをプッシュしたい場合は、通常、ロング ポーリング テクノロジーを使用します。つまり、クライアントはサーバーにリクエストを送信し、新しいデータがあるまでレスポンスを待ちます。返す前のデータを応答します。このアプローチの問題は、リクエストとレスポンスがペアになっていることで、リクエストが頻繁に発生すると、サーバーに多大な負荷がかかります。 WebSocketは通信確立後も長期間接続を維持することができ、サーバーがクライアントにメッセージを積極的にプッシュする機能を実現できます。

WebSocket の通信プロトコルは、HTTP と同様のハンドシェイクを使用して新しいセッションを開始し、両端で双方向のデータ送信を実行します。 WebSocket 通信プロトコルは、通常の HTTP プロトコルを通じて接続を確立した後、WebSocket 接続に変換できるため、特別なメソッドやポートを通じて接続する必要がなくなります。

WebSocket の実装

まず、サーバー側の PHP コードで、WebSocketServer クラスを作成し、関連メソッドを実装する必要があります。

class WebSocketServer {
    public function __construct($host, $port){
        $this->host = $host;
        $this->port = $port;
        $this->sockets = array();
        $this->users = array();
    }

    public function run(){
        $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        socket_bind($server, $this->host, $this->port);
        socket_listen($server);

        $this->sockets[] = $server;
        echo "WebSocket服务器运行在 $this->host:$this->port
";

        while(true){
            $new_sockets = $this->sockets;
            $write = NULL;
            $except = NULL;
            socket_select($new_sockets, $write, $except, NULL);
            foreach($new_sockets as $socket){
                if ($socket == $server){
                    $client = socket_accept($server);
                    $this->sockets[] = $client;
                    $this->users[] = array('socket'=>$client);
                } else {
                    $bytes = @socket_recv($socket, $buffer, 1024, MSG_DONTWAIT);
                    if ($bytes == 0) {
                        $index = $this->find_user_by_socket($socket);
                        if ($index >= 0) {
                            array_splice($this->users, $index, 1);
                        }
                        socket_close($socket);
                        $key = array_search($socket, $this->sockets);
                        array_splice($this->sockets, $key, 1);
                    } else {
                        $index = $this->find_user_by_socket($socket);
                        if($index >= 0) {
                            $msg = $buffer;
                            $this->handle_message($msg, $this->users[$index]);
                        }
                    }
                }
            }
        }
    }

    private function find_user_by_socket($socket){
        $found = -1;
        foreach($this->users as $index => $user){
            if ($user['socket'] == $socket){
                $found = $index;
                break;
            }
        }
        return $found;
    }

    private function handle_message($msg, $user) {
        // 处理新消息
    }
}

WebSocket プロトコルでは、メッセージは次で始まります。 4 ~ 10 バイトの長さのヘッダーで始まり、その後に実際のデータが続きます。上記のコードでは、長さのヘッダーを解析して、対応する長さのデータ部分を読み取る必要があります。

private function handle_message($msg, $user) {
    if(strlen($msg) === 0) {
        return;
    }

    $code = ord(substr($msg, 0, 1)) & 0x0F;
    switch ($code){
        case 0x01: // 文本数据
            $msg = substr($msg, 1);
            break;
        case 0x02: // 二进制数据
            $msg = substr($msg, 1);
            break;
        case 0x08: // 连接关闭
            $index = $this->find_user_by_socket($user['socket']);
            if ($index >= 0) {
                array_splice($this->users, $index, 1);
            }
            socket_close($user['socket']);
            $key = array_search($user['socket'], $this->sockets);
            array_splice($this->sockets, $key, 1);
            return;
        case 0x09: // ping
        case 0x0A: // pong
            return;
        default:
            return;
    }

    // 处理新消息
}

handle_message メソッドでは、ダンプや他のクライアントへの送信など、クライアントから受信した新しいメッセージを処理できます。

WebSocket のクライアント側実装

クライアント側では、JavaScript を使用して WebSocket 接続を作成し、メッセージを送受信する必要があります。以下は、WebSocket サーバーに接続するための JavaScript コードです。

var ws = new WebSocket("ws://localhost:8080/");
ws.onopen = function() {
    console.log("Connected to WebSocket server");
};

ws.onmessage = function(evt) {
    console.log("Received message: " + evt.data);
};

ws.onclose = function(evt) {
    console.log("Disconnected from WebSocket server");
};

上記のコードでは、WebSocket コンストラクターを使用して WebSocket オブジェクトを作成し、それを WebSocket サーバーに接続します。また、WebSocket の接続ステータスと受信メッセージを監視するために、いくつかのイベント リスナー (onopen、onmessage、および onclose) をセットアップしました。

WebSocket サーバーにデータを送信する場合は、WebSocket オブジェクトの send メソッドを使用できます。

ws.send("Hello, WebSocket server!");

WebSocket サーバーから新しいメッセージを受信すると、onmessage イベントが発生します。トリガーされると、イベントオブジェクトから受信データを取得できます。

リアルタイム コラボレーション ツールのアプリケーション

WebSocket 通信のサポートにより、実際のコラボレーション ツール アプリケーションを開発できます。コラボレーション ツールでは、次の機能を実装する必要があります。

  • ユーザーのログイン/ログアウト
  • インスタント チャット メッセージの送信
  • 複数のユーザーが同じドキュメントを共同編集する
  • 変更とフィードバックを他のユーザーに送信する

これらの関数をさまざまな PHP クラスに実装し、実際のビジネス ニーズに応じて改良することができます。以下は例です:

class WebSocketChat {

    private $users = array();

    public function onOpen($user){
        $this->users[$user['id']] = $user;
        $this->sendToAll(array('type'=>'notice','from'=>'System','msg'=>"{$user['name']}进入聊天室"));
    }

    public function onMessage($user, $msg){
        $this->sendToAll(array('type'=>'msg','from'=>$user['name'],'msg'=>$msg));
    }

    public function onClose($user){
        unset($this->users[$user['id']]);
        $this->sendToAll(array('type'=>'notice','from'=>'System','msg'=>"{$user['name']}离开聊天室"));
    }

    private function sendToAll($msg){
        foreach($this->users as $user){
            $this->send($user, $msg);
        }
    }

    private function send($user, $msg){
        socket_write($user['socket'], $this->encode(json_encode($msg)));
    }

    private function encode($msg){
        $len = strlen($msg);
        if($len <= 125){

        }

        if($len <= 65535){

        }


    }
}

上の例では、ログイン、ログアウト、メッセージの送信、その他の機能を含む単純なチャット ルームを実装しました。 WebSocketChat クラスでは、ユーザーのリストを維持し、ユーザーが接続したときに onOpen メソッドを通じて新しいユーザーを追加します。ユーザーからメッセージを受信すると、sendToAll メソッドを呼び出して、接続しているすべてのユーザーにメッセージを送信します。ユーザーが切断すると、そのユーザーはユーザー リストから削除され、ユーザーが離脱したことが他のユーザーに通知されます。

結論

この記事では、PHP と WebSocket を使用して Web ベースのリアルタイム コラボレーション ツールを実装する方法を紹介し、関連するコード例を示しました。インターネットとモバイル デバイスの普及に伴い、リアルタイム コラボレーション ツールの需要はますます高まるため、開発者は実際のニーズに基づいて二次開発を行い、ユーザーのニーズにさらに応えることができます。

以上がPHP と WebSocket を使用してリアルタイム コラボレーション ツールを開発する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。