ホームページ  >  記事  >  バックエンド開発  >  WebSocket に基づいてチャット ルームを構築する PHP の実践

WebSocket に基づいてチャット ルームを構築する PHP の実践

墨辰丷
墨辰丷オリジナル
2018-05-31 10:43:217188ブラウズ

この記事ではphp+websocketで簡単なチャットルームを構築する実践を中心に説明していますので、必要な方は記事内のphpとwebsocketの内容を参照してください。

この記事の例では、WebSocket に基づいて PHP で単純なチャット ルームを構築する実践について説明します。皆さんの参考に共有してください。詳細は以下のとおりです:
1. はじめに

会社のゲームに簡易チャットルームがあることに気づき、PHPを使って簡易チャットを作ってみようと思いました。部屋。そこで、さまざまな情報を収集し、ドキュメントを読み、事例を探し、簡単なチャット ルームを自分で書きました。

http 接続は、短い接続と長い接続に分けられます。短い接続は通常、ajax を使用して実装でき、長い接続は WebSocket です。短い接続は実装が比較的簡単ですが、消費するリソースが多すぎます。 Websocket は効率的ですが、互換性に関していくつかの問題があります。 Websocket は html5 のリソースです

2. フロントエンド

WebSocket の実装は非常にシンプルで簡単です

3. Websocket の難しさは主に次のとおりです。バックエンド内

3.1 websocket接続プロセスwebsocket通信図 これは、クライアントとサーバー間の単純な通信図です。PHPが主に行うことは、暗号化キーを受け取り、それを返してソケットの作成とハンドシェイク操作を完了することです


下の図はサービスの詳細です エンド側のWebSocket処理のフローチャート

3.2 コードの練習


サーバーによって実行されるプロセスは大まかに次のとおりです:

接続を待機しているソケットのプロセスをハングアップします

ソケット接続が確立された後にソケットをトラバースする インターフェース配列
  1. ハンドシェイクがない場合はハンドシェイク操作を実行する ハンドシェイクがある場合、データは解析されて出力用のバッファーに書き込まれます
  2. 以下はサンプルコードです (クラスを書いたので、コードは関数の段落に従って分割されています)。記事の最後には、github アドレスと私が遭遇したいくつかの落とし穴が記載されています
  3. 1. まず、ソケットを作成します


  4. //连接websocket
    
    var ws = new WebSocket("ws://127.0.0.1:8000");
    
    //成功连接websoc的时候
    
    ws.onopen = function(){}
    
    //成功获取服务端输出的消息
    
    ws.onmessage = function(e){}
    
    //连接错误的时候
    ws.onerror = function(){}
    
    //向服务端发送数据
    
    ws.send();


2. ソケットを配列に配置します

//建立套接字
    public function createSocket($address,$port)
    {
      //创建一个套接字
      $socket= socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
      //设置套接字选项
      socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
      //绑定IP地址和端口
      socket_bind($socket,$address,$port);
      //监听套接字
      socket_listen($socket);
      return $socket;
    }

3. 中断されたプロセスはソケット配列を走査し、主な操作はここで完了します

public function __construct($address,$port)
    {
      //建立套接字
      $this->soc=$this->createSocket($address,$port);
      $this->socs=array($this->soc);

    }

4. WebSocket のコンテンツを受信し、Sec-WebSocket-Key からキーを取得するには: そして渡します。 バッファーに書き込まれた暗号化アルゴリズムはクライアントによって検証されます (自動検証には弊社の処理は必要ありません)


public function run(){
      //挂起进程
      while(true){
        $arr=$this->socs;
        $write=$except=NULL;
        //接收套接字数字 监听他们的状态
        socket_select($arr,$write,$except, NULL);
        //遍历套接字数组
        foreach($arr as $k=>$v){
          //如果是新建立的套接字返回一个有效的 套接字资源
          if($this->soc == $v){
            $client=socket_accept($this->soc);
            if($client <0){
              echo "socket_accept() failed";
            }else{
              // array_push($this->socs,$client);
              // unset($this[]);
              //将有效的套接字资源放到套接字数组
              $this->socs[]=$client;
            }
          }else{
            //从已连接的socket接收数据 返回的是从socket中接收的字节数
            $byte=socket_recv($v, $buff,20480, 0);
            //如果接收的字节是0
            if($byte<7)
              continue;
            //判断有没有握手没有握手则进行握手,如果握手了 则进行处理
            if(!$this->hand[(int)$client]){
              //进行握手操作
              $this->hands($client,$buff,$v);
            }else{
              //处理数据操作
              $mess=$this->decodeData($buff);
                //发送数据
              $this->send($mess,$v);
            }
          }
        }
      }
    }

5.クライアントのデータを解析します (ここでは暗号化していません。必要に応じて自分で暗号化できます)


6. ソケットをバッファに書き込みます


7. メソッドを実行します

。 github アドレス git@github.com:rsaLive/websocket.git

①server.php を実行する

を制御するのが最善です。server.php スクリプト ディレクトリに移動します (最初に php -v を実行して、php が設定されているかどうかを確認できます。 Linux 設定はありません。bash Windows でパスを設定してください)

php -f server.php

エラーがある場合は、プロンプトが表示されます

②サーバー経由でHTMLファイルにアクセスします

8. ピットを踏んだ場合は、デバッグ作業を開いてエラーを簡単に確認してください

①server.php ハングしたプロセスを出力できます。はい、問題が発生した場合は、コードに印刷を追加できます。デバッグ

各判断をマークして、コードが実行されているセクションをコンソールで確認できます

しかし、コードを変更した後は毎回スクリプトphpserver.phpを再実行する必要があります

②このエラーが発生する場合は、次のことが考えられます。

1. サーバーとのソケットの初期化時にデータを送信する (サーバーとの最初の検証ハンドシェイク中にコンテンツは送信できません)

2. 検証済みの場合 ただし、この状況はクライアントが検証済みの場合にも発生します。送信されない、または送信されたメッセージが空であるため、接続されているソケットのデータを確認する必要があります

public function hands($client,$buff,$v)
    {
      //提取websocket传的key并进行加密 (这是固定的握手机制获取Sec-WebSocket-Key:里面的key)
      $buf = substr($buff,strpos($buff,&#39;Sec-WebSocket-Key:&#39;)+18);
      //去除换行空格字符
      $key = trim(substr($buf,0,strpos($buf,"\r\n")));
       //固定的加密算法
      $new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
      $new_message = "HTTP/1.1 101 Switching Protocols\r\n";
      $new_message .= "Upgrade: websocket\r\n";
      $new_message .= "Sec-WebSocket-Version: 13\r\n";
      $new_message .= "Connection: Upgrade\r\n";
      $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
      //将套接字写入缓冲区
      socket_write($v,$new_message,strlen($new_message));
      // socket_write(socket,$upgrade.chr(0), strlen($upgrade.chr(0)));
      //标记此套接字握手成功
      $this->hand[(int)$client]=true;
    }

以上がこの記事の全内容です。皆様の学習に役立つことを願っています。

関連する推奨事項:

PHP のランダムな赤い封筒アルゴリズムの詳細な説明

PHP を使用して近くの人を検索する

PHP 長時間接続のユースケース分析

以上がWebSocket に基づいてチャット ルームを構築する PHP の実践の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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