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('Y-m-d H:i:s')); $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 'unset index is:'.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 . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 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('localhost', 4000);
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>
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.
Erklärung, wie Sie die gemeinsame WeChat-Lieferadresse mit PHP erhalten
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!