Beispielerklärung zur Implementierung der Socket-Push-Technologie in PHP

jacklove
Freigeben: 2023-04-02 15:34:01
Original
1640 Leute haben es durchsucht

Der unten stehende Herausgeber wird Ihnen ein Beispiel für die Implementierung der Socket-Push-Technologie durch PHP vorstellen. Es hat einen guten Referenzwert und ich hoffe, dass es für alle hilfreich sein wird. Folgen wir dem Editor, um einen Blick darauf zu werfen

Vor dem Aufkommen von Sockets gab es bereits Lösungen wie geplante Ajax-Anfragen und lange Abfragen, aber sie konnten die Anforderungen nicht erfüllen, sodass Sockets geboren wurden.

Socket-Grundfunktionen Socket

Zusammenfassung häufig verwendeter Socket-Funktionen

Serverseite: socket_create erstellt einen Socket und legt grundlegende Parameter fest

socket_bind bindet IP und Portnummer

socket_listen lauscht

socket_accept Client-Verbindung

  socket_read liest Client-Daten

socket_write sendet Daten an einen einzelnen Client

socket_close schließt die Verbindung

Client: socket_create erstellt einen Socket und legt grundlegende Parameter fest

socket_connect stellt eine Verbindung zum Socket her

socket_write sendet Daten an den Server

socket_read liest Serverdaten

socket_close schließt Nicht viel Um etwas über die Verbindung von

H5websocket zu sagen, gehen Sie einfach auf den Link

OK und beginnen Sie mit der Veröffentlichung des Codes~

-------- - ----------------------------------------------Trennlinie

Servercode:

<?php
class WS {
 var $master;
 var $sockets = array();
 var $debug = false;//true为调试模式,输出log日志
 var $handshake = array();
 function __construct($address, $port){
 $this->master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed");
 socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed");
 socket_bind($this->master, $address, $port)  or die("socket_bind() failed");
 socket_listen($this->master,20)  or die("socket_listen() failed");
 
 $this->sockets[] = $this->master;
 $this->say("Server Started : ".date(&#39;Y-m-d H:i:s&#39;));
 $this->say("Listening on : ".$address." port ".$port);
 $this->say("Master socket : ".$this->master."\n");
 
 while(true){
 $socketArr = $this->sockets;
 $write = NULL;
 $except = NULL;
 socket_select($socketArr, $write, $except, NULL); //自动选择来消息的socket 如果是握手 自动选择主机
 foreach ($socketArr as $socket){
 if ($socket == $this->master){ //主机
  $client = socket_accept($this->master);
  if ($client < 0){
  $this->log("socket_accept() failed");
  continue;
  } else{
  $this->connect($client);
  }
 } else {
  $bytes = @socket_recv($socket,$buffer,2048,0);
  if ($bytes == 0){
  $this->disConnect($socket);
  }
  else{
  $key = array_search($socket, $this->sockets);
  if (empty($this->handshake) || !isset($this->handshake[$key]) || !$this->handshake[$key]){
  $this->doHandShake($socket, $buffer, $key);
  }
  else{
  $buffer = $this->decode($buffer);
  echo $buffer.PHP_EOL;
  $key = array_search($socket, $this->sockets);
  $arr = $this->sockets;
  array_shift($arr);
  foreach ($arr as $s){
  $this->send($s, $buffer);
  }
  }
  }
 }
 }
 }
 }
 
 function send($client, $msg){
 $msg = $this->frame($msg);
 socket_write($client, $msg, strlen($msg));
 }
 function connect($socket){
 array_push($this->sockets, $socket);
 $this->say("\n" . $socket . " CONNECTED!");
 $this->say(date("Y-n-d H:i:s"));
 }
 function disConnect($socket){
 $index = array_search($socket, $this->sockets);
 socket_close($socket);
 $this->say($socket . " DISCONNECTED!");
 if ($index >= 0){
 echo &#39;unset index is:&#39;.PHP_EOL;
 unset($this->sockets[$index]);
 }
 }
 function doHandShake($socket, $buffer, $handKey){
 $this->log("\nRequesting handshake...");
 $this->log($buffer);
 list($resource, $host, $origin, $key) = $this->getHeaders($buffer);
 $this->log("Handshaking...");
 $upgrade = "HTTP/1.1 101 Switching Protocol\r\n" .
  "Upgrade: websocket\r\n" .
  "Connection: Upgrade\r\n" .
  "Sec-WebSocket-Accept: " . $this->calcKey($key) . "\r\n\r\n"; //必须以两个回车结尾
 $this->log($upgrade);
 $sent = socket_write($socket, $upgrade, strlen($upgrade));
 $this->handshake[$handKey]=true;
 $this->log("Done handshaking...");
 return true;
 }
 function getHeaders($req){
 $r = $h = $o = $key = null;
 if (preg_match("/GET (.*) HTTP/" ,$req,$match)) { $r = $match[1]; }
 if (preg_match("/Host: (.*)\r\n/" ,$req,$match)) { $h = $match[1]; }
 if (preg_match("/Origin: (.*)\r\n/" ,$req,$match)) { $o = $match[1]; }
 if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$req,$match)) { $key = $match[1]; }
 return array($r, $h, $o, $key);
 }
 function calcKey($key){
 //基于websocket version 13
 $accept = base64_encode(sha1($key . &#39;258EAFA5-E914-47DA-95CA-C5AB0DC85B11&#39;, true));
 return $accept;
 }
 function decode($buffer) {
 $len = $masks = $data = $decoded = null;
 $len = ord($buffer[1]) & 127;
 if ($len === 126) {
 $masks = substr($buffer, 4, 4);
 $data = substr($buffer, 8);
 } 
 else if ($len === 127) {
 $masks = substr($buffer, 10, 4);
 $data = substr($buffer, 14);
 } 
 else {
 $masks = substr($buffer, 2, 4);
 $data = substr($buffer, 6);
 }
 for ($index = 0; $index < strlen($data); $index++) {
 $decoded .= $data[$index] ^ $masks[$index % 4];
 }
 return $decoded;
 }
 function frame($s){
 $a = str_split($s, 125);
 if (count($a) == 1){
 return "\x81" . chr(strlen($a[0])) . $a[0];
 }
 $ns = "";
 foreach ($a as $o){
 $ns .= "\x81" . chr(strlen($o)) . $o;
 }
 return $ns;
 }
 
 function say($msg = ""){
 echo $msg . "\n";
 }
 function log($msg = ""){
 if ($this->debug){
 echo $msg . "\n";
 } 
 }
}
 
new WS(&#39;localhost&#39;, 4000);
Nach dem Login kopieren

Clientcode ( H5 ):

<html>
 <head>
 <title>demo</title>
 <script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
 </head>
 <body>
 <input type="text" id="content">
 <input type="button" value="send" id="send">
 <script type="text/javascript">
  var ws = new WebSocket("ws://localhost:4000");
  ws.onopen = function(){
  console.log("握手成功");
  }
  ws.onmessage = function(e){
  console.log("message:" + e.data);
  }
  ws.onerror = function(){
  console.log("error");
  }
  $("#send").click(function(){
  content = $("#content").val();
  console.log(content);
  ws.send(content);
  })
 </script>
 </body>
</html>
Nach dem Login kopieren

Führen Sie dann php demo.php aus, um den Socket zu öffnen (stehlen Sie einen Trick aus dem Betrieb und der Wartung, führen Sie nohup unter aus Linux PHP demo.php & kann im Hintergrund ausgeführt werden) und der Browser kann mehrere index.html öffnen, um die Kommunikation herzustellen.

Codeanalyse:

1 Das Attribut $sockets-Array speichert jede akzeptierte Verbindung (ich weiß nicht, ob das die richtige Beschreibung ist );

2. Das Attribut $handshake speichert, ob sich die Verbindung im verbundenen Zustand befindet.

Das obige Beispiel für die Implementierung der Socket-Push-Technologie ist der gesamte vom Editor geteilte Inhalt Ich hoffe, es kann Ihnen eine Referenz geben. Ich hoffe auch, dass jeder die chinesische PHP-Website unterstützt.

Artikel, die Sie interessieren könnten:

Erklärung, wie Sie die gemeinsame WeChat-Lieferadresse mit PHP erhalten

Detaillierte Erläuterung der Schritte zum Bereitstellen des thinkphp5-Projekts auf dem virtuellen Cloud-Host

Erklärung der Methode zum Crawlen der Kugou-Wiedergabeliste mit der PHPCrawl-Crawler-Bibliothek

Das obige ist der detaillierte Inhalt vonBeispielerklärung zur Implementierung der Socket-Push-Technologie in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!