Position actuelle: Accueil> Derniers articles> Communication avec le client WebSocket frontal: Idée d'implémentation de socket_accept

Communication avec le client WebSocket frontal: Idée d'implémentation de socket_accept

M66 2025-05-20

Dans les applications Web, WebSocket fournit un moyen d'établir un canal de communication duplex complet entre le client et le serveur. Par rapport aux demandes HTTP traditionnelles, WebSocket permet au serveur de pousser activement les messages au client. Bien que PHP ne soit pas le langage le plus approprié pour les longues connexions au sens traditionnel, il peut toujours implémenter des services WebSocket simples grâce à une programmation de socket sous-jacente. Cet article présentera comment utiliser la fonction Socket_Accept de PHP pour réaliser la communication avec le client WebSocket frontal.

Condition préalable

Afin d'utiliser la fonctionnalité de socket de PHP, vous devez vous assurer que l'extension Sockets est activée en PHP. Il peut être activé dans php.ini :

 extension=sockets

Redémarrez ensuite votre service PHP.

Créer un serveur WebSocket

Le processus de poignée de main de WebSocket suit certaines spécifications du protocole. Nous devons effectuer une confirmation de poignée de main au niveau du protocole HTTP après avoir reçu la demande du client avant de pouvoir effectuer la communication de trame de données WebSocket.

Voici un exemple de script PHP complet:

 <?php
$host = '0.0.0.0';
$port = 8080;

$serverSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($serverSocket, $host, $port);
socket_listen($serverSocket);

echo "WebSocket Le serveur commence à $host:$port\n";

while (true) {
    $clientSocket = socket_accept($serverSocket);
    if ($clientSocket === false) {
        continue;
    }

    // Lire l&#39;en-tête de la demande du client
    $request = socket_read($clientSocket, 1024);
    if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $request, $matches)) {
        $key = trim($matches[1]);
        $acceptKey = base64_encode(pack('H*', sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
        $headers = "HTTP/1.1 101 Switching Protocols\r\n";
        $headers .= "Upgrade: websocket\r\n";
        $headers .= "Connection: Upgrade\r\n";
        $headers .= "Sec-WebSocket-Accept: $acceptKey\r\n\r\n";
        socket_write($clientSocket, $headers);
        echo "WebSocket La poignée de main est terminée。\n";
    }

    // Lire et envoyer simples WebSocket information
    while (true) {
        $data = socket_read($clientSocket, 2048);
        if ($data === false) {
            break;
        }

        $decoded = unmask($data);
        echo "接收到客户端information: $decoded\n";

        $response = mask("Ce que vous avez envoyé est: $decoded");
        socket_write($clientSocket, $response);
    }

    socket_close($clientSocket);
}

socket_close($serverSocket);

// Analyse WebSocket cadre
function unmask($payload) {
    $length = ord($payload[1]) & 127;
    if ($length == 126) {
        $masks = substr($payload, 4, 4);
        $data = substr($payload, 8);
    } elseif ($length == 127) {
        $masks = substr($payload, 10, 4);
        $data = substr($payload, 14);
    } else {
        $masks = substr($payload, 2, 4);
        $data = substr($payload, 6);
    }

    $text = '';
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i % 4];
    }
    return $text;
}

// structure WebSocket 数据cadre
function mask($text) {
    $b1 = 0x81; // FIN=1, opcode=0x1 (text)
    $length = strlen($text);

    if ($length <= 125) {
        $header = pack('CC', $b1, $length);
    } elseif ($length <= 65535) {
        $header = pack('CCn', $b1, 126, $length);
    } else {
        $header = pack('CCNN', $b1, 127, 0, $length);
    }

    return $header . $text;
}
?>

Exemple du client frontal

À l'avant, vous pouvez communiquer avec le service PHP WebSocket de la manière suivante:

 <script>
    const socket = new WebSocket("ws://m66.net:8080");

    socket.onopen = () => {
        console.log("La connexion a été établie");
        socket.send("Bonjour PHP WebSocket!");
    };

    socket.onmessage = (event) => {
        console.log("收到information:", event.data);
    };

    socket.onclose = () => {
        console.log("La connexion est fermée");
    };
</script>

Remarque: ws: //m66.net: 8080 Voici l'adresse de votre serveur. Veuillez définir le nom de domaine et la cartographie du port en fonction de l'environnement de déploiement.

Résumer

En utilisant Socket_Accept de PHP et des fonctions connexes, nous pouvons implémenter une logique de base du serveur WebSocket. Cette méthode convient à l'apprentissage et à des fins expérimentales. Pour les environnements de production, il est recommandé d'utiliser des solutions de performance plus élevées telles que Ratchet, Swoole ou utiliser un serveur WebSocket dédié (comme Node.js, GO).

Bien que PHP ne soit pas conçu pour des connexions longues, sa prise sous-jacente est puissante et peut répondre aux besoins de communication bidirectionnels de base. Grâce aux exemples de cet article, vous pouvez créer un simple serveur PHP WebSocket pour interagir avec le client frontal.