Maison  >  Article  >  développement back-end  >  Explication détaillée d'exemples d'utilisation de Websocket en php

Explication détaillée d'exemples d'utilisation de Websocket en php

伊谢尔伦
伊谢尔伦original
2018-05-15 17:41:2621885parcourir

Qu'est-ce que WebSocket ?

WebSocket est un protocole persistant, non persistant par rapport à http. Pour donner un exemple simple, le cycle de vie de http1.0 est défini par requête, c'est-à-dire une requête et une réponse. Pour http, la session entre le client et le serveur se termine ici en http1, il y a une légère amélioration, c'est-à-dire que le maintien en vie est ajouté, c'est-à-dire que plusieurs requêtes de requête et plusieurs opérations d'acceptation de réponse peuvent être effectuées dans une seule connexion http. Cependant, dans la communication en temps réel, cela ne joue pas un grand rôle. Les requêtes HTTP peuvent uniquement être initiées par le client et le serveur peut renvoyer des informations. Autrement dit, le serveur ne peut pas transmettre activement d'informations au client et ne peut pas répondre aux exigences. de communication en temps réel. WebSocket peut établir des connexions persistantes, c'est-à-dire que le client n'a besoin que d'effectuer une poignée de main et la communication de données peut continuer après le succès. Il convient de noter que WebSocket implémente une communication en duplex intégral entre le client et le serveur, c'est-à-dire que le serveur peut. communiquer activement lorsque les données sont mises à jour.

La figure suivante montre la partie poignée de main lors de l'établissement d'une connexion websocket entre le client et le serveur. Cette partie peut être complétée très facilement dans node, car le module net fourni par node l'a déjà fait pour les sockets. . Sans traitement d'encapsulation, les développeurs n'ont qu'à prendre en compte l'interaction des données lors de leur utilisation sans avoir à s'occuper de l'établissement des connexions.

Explication détaillée dexemples dutilisation de Websocket en php

Contenu de la conversation de la poignée de main entre le client et le serveur lors de l'établissement d'un socket, c'est-à-dire demande et réponse

a. Les informations demandées par le client au serveur lors de l'établissement de WebSocket

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket //告诉服务器现在发送的是WebSocket协议
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== //是一个Base64 encode的值,这个是浏览器随机生成的,用于验证服务器端返回数据是否是WebSocket助理
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: php.cn

b. par le client, il traite les données selon le protocole WebSocket Traitement et retour, y compris le cryptage et autres opérations sur Sec-WebSocket-Key

HTTP/1.1 101 Switching Protocols
Upgrade: websocket //依然是固定的,告诉客户端即将升级的是Websocket协议,而不是mozillasocket,lurnarsocket或者shitsocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= //这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key,也就是client要求建立WebSocket验证的凭证
Sec-WebSocket-Protocol: chat

Explication du processus d'établir un socket en PHP

1 En PHP, la communication socket est établie entre le client et le serveur. Tout d'abord, créez un socket en PHP. et écoutez les informations sur le port. Le code est le suivant :

<?php
//传相应的IP与端口进行创建socket操作
function WebSocket($address,$port){
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);//1表示接受所有的数据包
socket_bind($server, $address, $port);
socket_listen($server);return $server;
}
?>

2. Concevez une boucle pour suspendre le canal WebSocket pour recevoir, traiter et envoyer des données

<?php
//对创建的socket循环进行监听,处理数据    
function run(){
  //死循环,直到socket断开
  while(true){
    $changes=$this->sockets;
    $write=NULL;
    $except=NULL;
    /*
    //这个函数是同时接受多个连接的关键,我的理解它是为了阻塞程序继续往下执行。
    socket_select ($sockets, $write = NULL, $except = NULL, NULL);
    $sockets可以理解为一个数组,这个数组中存放的是文件描述符。当它有变化(就是有新消息到或者有客户端连接/断开)时,socket_select函数才会返回,继续往下执行。 
    $write是监听是否有客户端写数据,传入NULL是不关心是否有写变化。 
    $except是$sockets里面要被排除的元素,传入NULL是”监听”全部。 
    最后一个参数是超时时间 
    如果为0:则立即结束 
    如果为n>1: 则最多在n秒后结束,如遇某一个连接有新动态,则提前返回 
    如果为null:如遇某一个连接有新动态,则返回
    */
    socket_select($changes,$write,$except,NULL);
    foreach($changes as $sock){
      //如果有新的client连接进来,则
      if($sock==$this->master){
        //接受一个socket连接
        $client=socket_accept($this->master);
        //给新连接进来的socket一个唯一的ID
        $key=uniqid();
        $this->sockets[]=$client;  //将新连接进来的socket存进连接池
        $this->users[$key]=array(
          &#39;socket&#39;=>$client,  //记录新连接进来client的socket信息
          &#39;shou&#39;=>false       //标志该socket资源没有完成握手
        );
        //否则1.为client断开socket连接,2.client发送信息
      }else{
        $len=0;
        $buffer=&#39;&#39;;
        //读取该socket的信息,注意:第二个参数是引用传参即接收数据,第三个参数是接收数据的长度
        do{
          $l=socket_recv($sock,$buf,1000,0);
          $len+=$l;
          $buffer.=$buf;
        }while($l==1000);
        //根据socket在user池里面查找相应的$k,即健ID
        $k=$this->search($sock);
        //如果接收的信息长度小于7,则该client的socket为断开连接
        if($len<7){
          //给该client的socket进行断开操作,并在$this->sockets和$this->users里面进行删除
          $this->send2($k);
          continue;
        }
        //判断该socket是否已经握手
        if(!$this->users[$k][&#39;shou&#39;]){
          //如果没有握手,则进行握手处理
          $this->woshou($k,$buffer);
        }else{
          //走到这里就是该client发送信息了,对接受到的信息进行uncode处理
          $buffer = $this->uncode($buffer,$k);
          if($buffer==false){
            continue;
          }
          //如果不为空,则进行消息推送操作
          $this->send($k,$buffer);
        }
      }
    }
  }
}
?>

3. le travail préliminaire ci-dessus de WebSocket est terminé côté serveur, attendez que la connexion client se poursuive, il est très simple pour le client de créer un WebSocket, le code est le suivant :

var ws = new WebSocket("ws://IP:端口");
//握手监听函数
ws.onopen=function(){
  //状态为1证明握手成功,然后把client自定义的名字发送过去
  if(so.readyState==1){
    //握手成功后对服务器发送信息
    so.send(&#39;type=add&ming=&#39;+n);
  }
}
//错误返回信息函数
ws.onerror = function(){
  console.log("error");
};
//监听服务器端推送的消息
ws.onmessage = function (msg){
  console.log(msg);
}
//断开WebSocket连接
ws.onclose = function(){
  ws = false;
}

[Connexe recommandations de tutoriel]

1. "php.cn Dugu Jiujian (4)-php tutoriel vidéo

2. Un ensemble complet de tutoriels sur la programmation PHP de l'entrée au master

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn