Heim  >  Artikel  >  php教程  >  PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

高洛峰
高洛峰Original
2016-12-22 10:01:101091Durchsuche

Das Beispiel in diesem Artikel beschreibt die Praxis des Aufbaus eines einfachen Chatrooms in PHP basierend auf WebSocket. Teilen Sie es als Referenz mit allen. Die Details sind wie folgt:
1. Vorwort

Nachdem ich es verstanden hatte, wurde mir klar, dass es von node+websocket erstellt wurde Erstellen Sie einen einfachen Chatraum. Also habe ich verschiedene Informationen gesammelt, Dokumente gelesen, nach Beispielen gesucht und selbst einen einfachen Chatroom geschrieben.

HTTP-Verbindungen werden in kurze und lange Verbindungen unterteilt. Kurze Verbindungen können im Allgemeinen mit Ajax implementiert werden, lange Verbindungen sind Websockets. Kurze Verbindungen sind relativ einfach zu implementieren, verbrauchen jedoch zu viele Ressourcen. Websocket ist effizient, weist jedoch einige Kompatibilitätsprobleme auf. Websocket ist eine Ressource von HTML5

2. Front-End

Die Front-End-Implementierung von Websocket ist sehr einfach und unkompliziert

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

3. Backend

Schwierigkeiten von WebSocket hauptsächlich im Hintergrund

3.1 WebSocket-Verbindungsprozess
WebSocket-Kommunikationsdiagramm Dies ist ein einfaches Kommunikationsdiagramm zwischen dem Client und dem Server Akzeptieren Sie den Verschlüsselungsschlüssel und geben Sie ihn zurück, um die Socket-Word-Erstellung und den Handshake-Vorgang abzuschließen

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

Das folgende Bild ist ein detailliertes Flussdiagramm des Serververarbeitungs-Websockets

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

3.2 Code-Praxis

Der vom Server durchgeführte Prozess ist ungefähr:

Hängen Sie einen Socket-Prozess an Warten Sie auf die Verbindung

Durchlaufen Sie das Socket-Array, nachdem eine Socket-Verbindung besteht

Wenn kein Handshake vorliegt, führen Sie einen Handshake-Vorgang durch. Empfangen Sie die Daten, analysieren Sie sie und schreiben Sie sie in den Puffer zur Ausgabe

Das Folgende ist der Beispielcode (ich habe eine Klasse geschrieben, daher ist der Code nach Funktionen segmentiert. Am Ende des Artikels sind die Github-Adresse und einige Fallstricke aufgeführt, auf die ich gestoßen bin
1. Erstellen Sie zunächst einen Socket

//建立套接字
    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;
    }

2. Fügen Sie den Socket in das Array ein

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

3. Hängen Sie den Prozess auf. Durchlaufen Sie das Socket-Array. Die Hauptoperationen werden hier abgeschlossen

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);
            }
          }
        }
      }
    }

4. Der Handshake-Prozess besteht darin, den WebSocket-Inhalt vom Sec-WebSocket-Key zu empfangen: Holen Sie sich den Schlüssel und schreiben Sie ihn über den Verschlüsselungsalgorithmus in den Puffer. Der Client überprüft ihn (für die automatische Überprüfung ist keine Verarbeitung erforderlich)

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;
    }

5. Analyse Kundendaten (Ich habe sie hier nicht verschlüsselt, Sie können sie bei Bedarf selbst verschlüsseln)

//解析数据
    public function decodeData($buff)
    {
      //$buff 解析数据帧
      $mask = array();
      $data = &#39;&#39;;
      $msg = unpack(&#39;H*&#39;,$buff); //用unpack函数从二进制将数据解码
      $head = substr($msg[1],0,2);
      if (hexdec($head{1}) === 8) {
        $data = false;
      }else if (hexdec($head{1}) === 1){
        $mask[] = hexdec(substr($msg[1],4,2));
        $mask[] = hexdec(substr($msg[1],6,2));
        $mask[] = hexdec(substr($msg[1],8,2));
        $mask[] = hexdec(substr($msg[1],10,2));
          //遇到的问题 刚连接的时候就发送数据 显示 state connecting
        $s = 12;
        $e = strlen($msg[1])-2;
        $n = 0;
        for ($i=$s; $i<= $e; $i+= 2) {
          $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i,2)));
          $n++;
        }
        //发送数据到客户端
          //如果长度大于125 将数据分块
          $block=str_split($data,125);
          $mess=array(
            &#39;mess&#39;=>$block[0],
            );
        return $mess;         
      }

6. Schreiben Sie den Socket in den Puffer

//发送数据
    public function send($mess,$v)
    {
      //遍历套接字数组 成功握手的 进行数据群发
      foreach ($this->socs as $keys => $values) {
        //用系统分配的套接字资源id作为用户昵称
          $mess[&#39;name&#39;]="Tourist&#39;s socket:{$v}";
          $str=json_encode($mess);
          $writes ="\x81".chr(strlen($str)).$str;
          // ob_flush();
          // flush();
          // sleep(3);
          if($this->hand[(int)$values])
            socket_write($values,$writes,strlen($writes));
        }
    }

7. Ausführen der Methode

github Adresse git@github.com:rsaLive/websocket.git

① Am besten führen Sie server.php in der Konsole aus

Gehen Sie in das Skriptverzeichnis server.php (Sie können zuerst php - v um zu sehen, ob PHP konfiguriert ist, konfigurieren Sie den Pfad in Bash Windows unter Linux)

php -f server.php

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

Wenn ein Fehler auftritt, wird

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

②Zugriff auf HTML-Dateien über den Server angezeigt

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

8. Für Fallstricke, auf die getreten wurde, öffnen Sie das Debugging, um die Anzeige von Fehlern zu erleichtern

①server.php kann im hängenden Prozess verwendet werden. Gedruckte Ausgabe, wenn es ein Problem gibt, können Sie Drucken hinzufügen zum Code zum Debuggen

Sie können jedes Urteil markieren und in der Konsole überprüfen, in welchem ​​Abschnitt der Code ausgeführt wird

Aber nach jeder Änderung des Codes müssen Sie das Skript des PHP-Servers erneut ausführen .php

② Wenn dieser Fehler auftritt, kann es sein, dass

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

1. Daten senden, wenn der Socket mit dem Server initialisiert wird (Inhalte können währenddessen nicht gesendet werden erster Verifizierungs-Handshake mit dem Server)

2. Dies geschieht auch, wenn die Nachricht verifiziert wurde, der Client sie aber nicht gesendet hat oder die gesendete Nachricht leer ist

Überprüfen Sie also die Daten des angeschlossene Steckdose

PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket

③可能浏览器不支持或者服务端没有开启socket开始之前最好验证下

if (window.WebSocket){
  console.log("This browser supports WebSocket!");
} else {
  console.log("This browser does not support WebSocket.");
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。

更多PHP-Praxis zum Erstellen eines einfachen Chatrooms basierend auf WebSocket相关文章请关注PHP中文网!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn