Maison > développement back-end > tutoriel php > Comment créer un serveur WebSocket en PHP ?

Comment créer un serveur WebSocket en PHP ?

Susan Sarandon
Libérer: 2024-12-07 01:01:10
original
396 Les gens l'ont consulté

How to Build a WebSocket Server in PHP?

Comment créer un serveur WebSocket en PHP

La création d'un serveur WebSocket peut être une tâche difficile, surtout si vous rencontrez du code obsolète ou une documentation incomplète . Voici une solution détaillée pour vous guider tout au long du processus :

Code côté serveur :

<?php

set_time_limit(0);
ob_implicit_flush();

$master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($master, "localhost", 12345);
socket_listen($master, 20);

$sockets = array($master);
$users = array();

while (true) {
  $changed = $sockets;
  socket_select($changed, $write=NULL, $except=NULL, NULL);
  foreach ($changed as $socket) {
    if ($socket == $master) {
      $client = socket_accept($master);
      if ($client < 0) {
        echo "socket_accept() failed\n";
        continue;
      } else {
        connect($client);
      }
    } else {
      $bytes = @socket_recv($socket, $buffer, 2048, 0);
      if ($bytes == 0) {
        disconnect($socket);
      } else {
        $user = getuserbysocket($socket);
        if (!$user->handshake) {
          dohandshake($user, $buffer);
        } else {
          process($user, $buffer);
        }
      }
    }
  }
}

function connect($socket) {
  global $sockets, $users;
  $user = new User();
  $user->id = uniqid();
  $user->socket = $socket;
  array_push($users, $user);
  array_push($sockets, $socket);
  echo $socket." CONNECTED!\n";
}

function disconnect($socket) {
  global $sockets, $users;
  $found = null;
  $n=count($users);
  for ($i=0;$i<$n;$i++) {
    if ($users[$i]->socket == $socket) {
      $found = $i;
      break;
    }
  }
  if (!is_null($found)) {
    array_splice($users, $found, 1);
  }
  $index = array_search($socket, $sockets);
  socket_close($socket);
  echo $socket." DISCONNECTED!\n";
  if ($index>=0) {
    array_splice($sockets, $index, 1);
  }
}

function dohandshake($user, $buffer) {
  $headers = getheaders($buffer);
  $acceptkey = base64_encode(sha1($headers[4] . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
  $upgrade  = "HTTP/1.1 101 Switching Protocols\r\n" .
               "Upgrade: websocket\r\n" .
               "Connection: Upgrade\r\n" .
               "Sec-WebSocket-Accept: $acceptkey\r\n\r\n";
  socket_write($user->socket, $upgrade, strlen($upgrade));
  $user->handshake = true;
  echo "Done handshaking...\n";
}

function getheaders($req) {
  $r=$h=$u=$c=$key=$protocol=$version=$o=$data=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("/Upgrade: (.*)\r\n/", $req, $match)) {
    $u = $match[1];
  }
  if (preg_match("/Connection: (.*)\r\n/", $req, $match)) {
    $c = $match[1];
  }
  if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $req, $match)) {
    $key = $match[1];
  }
  if (preg_match("/Sec-WebSocket-Protocol: (.*)\r\n/", $req, $match)) {
    $protocol = $match[1];
  }
  if (preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $req, $match)) {
    $version = $match[1];
  }
  if (preg_match("/Origin: (.*)\r\n/", $req, $match)) {
    $o = $match[1];
  }
  if (preg_match("/\r\n(.*?)$/", $req, $match)) {
    $data = $match[1];
  }
  return array($r,$h,$u,$c,$key,$protocol,$version,$o,$data);
}

function getuserbysocket($socket) {
  global $users;
  $found = null;
  foreach ($users as $user) {
    if ($user->socket == $socket) {
      $found = $user;
      break;
    }
  }
  return $found;
}

class User {
  var $id;
  var $socket;
  var $handshake;
}

?>
Copier après la connexion

Côté client Code :

var connection = new WebSocket('ws://localhost:12345');

connection.onopen = function () {
  connection.send('Ping');
};

connection.onerror = function (error) {
  console.log('WebSocket Error ' + error);
};

connection.onmessage = function (e) {
  console.log('Server: ' + e.data);
};
Copier après la connexion

Dépannage :

Si vous rencontrez le message d'erreur « Firefox ne peut pas établir de connexion au serveur à l'adresse ws:// localhost:12345/", vérifiez les points suivants :

  • Assurez-vous que le code de votre serveur s'exécute sur le port 12345.
  • Vérifiez que votre code côté client se connecte au nom d'hôte et au port corrects.
  • Assurez-vous que votre code implémente correctement la procédure de prise de contact WebSocket comme indiqué dans la spécification RFC 6455.
  • Assurez-vous que vous gérez correctement les cadres et le masquage WebSocket.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal