【问题标题】:JavaScript WebSocket & PHP SocketJavaScript WebSocket 和 PHP 套接字
【发布时间】:2022-08-05 02:52:41
【问题描述】:

我想使用 JavaScript 和 PHP 建立一个套接字连接。 我使用 JS WebSocket 和 PHP Socket。 如果我在服务器上本地运行 PHP 脚本,那么它们会相互通信并建立连接(屏幕截图1)。

脚本在服务器上结束后,套接字不会立即可用(截图2)。

如果我使用 WebSocket 在浏览器中打开客户端脚本,则响应以难以理解的编码固定,并且在文本中不是恒定的,您可以在其上看到的只有请求来自的域名(屏幕截图3)。

端口:3000,在 80 和 443 上,套接字未 ping。

问题:浏览器以难以理解的编码响应的原因是什么,是否有必要在 JS 中为握手预先准备标题文本?我在这个论坛上读到,只能在 WebSocket([url], [protocol]) 中选择指定协议。

提前感谢您的建议。

例子

回答

 ▒▒▒▒▒2B▒~▒˼[▒▒p\'▒w▒
▒%▒▒c▒/ e▒O▒&ߍ▒▒L▒}▒▒4▒▒W▒▒▒4▒▒.▒▒ ▒▒̨̩▒+▒/▒,▒0▒▒▒▒/5▒▒▒domain.name▒
                                                                                                                       ▒▒
 #                                                                                                                   3+)/▒ ▒~l▒se▒▒lxk▒aG?i▒i0
 ;m^eCG▒▒jI-+JJ
               ih2**▒

==============================

服务器代码

<?php
// set some variables
$url_site = \'domain.name\';
$host = gethostbyname($url_site);
$port = getservbyname(\'https\', \'tcp\');
$port = 3000;

// don\'t timeout!
set_time_limit(0);
$flag_handshake = false;
$client = null;
header(\"Content-Type:application/javascript; charset=utf-8\");

// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die(\"Could not create socket\\n\");
echo serialize($socket).\" socket_create...\\n\\n\";

// bind socket to port
$result = socket_bind($socket, $host, $port) or die(\"Could not bind to socket\\n\");
echo serialize($socket).\" socket_bind...\\n\\n\";

// start listening for connections
$result = socket_listen($socket, 0) or die(\"Could not set up socket listener\\n\");
echo serialize($socket).\" socket_listen...\\n\\n\";
echo \"Ready to receive on wss://$host:$port/ ...\\n\";

do {
    if (!$client) {
        // accept incoming connections
        // client another socket to handle communication
        $client = socket_accept($socket) or die(\"Could not accept incoming connection\\n\");
        echo \"Client << $client >> has connected.\\n\";
    }

    $bytes =  @socket_recv($client, $data, 2048, 0);
    if ($flag_handshake == false) {
        if ((int)$bytes == 0)
            continue;
        print(\"Handshaking headers from client: \". mb_detect_encoding($data) .\" - \". $data .\"\\n\");
        echo $client .\" -->>LEN<<-- \". $bytes;
        if (handshake($client, $data, $socket)) {
            $flag_handshake = true;
        }
    }
    elseif($flag_handshake == true) {
        if ($data != \"\") {
            $decoded_data = unmask($data);
            print(\"< \". $decoded_data .\"\\n\");
            $response = strrev($decoded_data);
            socket_write($client, encode($response));
            print(\"> \". $response .\"\\n\");
            socket_close($client);
            $client = null;
            $flag_handshake = false;
        }
    }
} while (true);

// close sockets
socket_close($client);
socket_close($socket);

function handshake($client, $headers, $socket) {
    print(\" [ HEADER: \" . $headers .\" ] \");
    if (preg_match(\"/Sec-WebSocket-Version: (.*)\\r\\n/\", $headers, $match)) {
        $version = $match[1];
                    //$version = 333;
    } else {
        print(\" [ The client doesn\'t support WebSocket ] \");
        return false;
                    //$version = 111;
    }

    if ($version == 13) {
        // Extract header variables
        if (preg_match(\"/GET (.*) HTTP/\", $headers, $match))
            $root = $match[1];
        if (preg_match(\"/Host: (.*)\\r\\n/\", $headers, $match))
            $host = $match[1];
        if (preg_match(\"/Origin: (.*)\\r\\n/\", $headers, $match))
            $origin = $match[1];
        if (preg_match(\"/Sec-WebSocket-Key: (.*)\\r\\n/\", $headers, $match))
            $key = $match[1];

        $acceptKey = $key.\'258EAFA5-E914-47DA-95CA-C5AB0DC85B11\';
        $acceptKey = base64_encode(sha1($acceptKey, 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($client, $upgrade);
        return true;
    } else {
        print(\"WebSocket version 13 required (the client supports version {$version})\");
        return false;
    }
}

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;
}

function encode($text) {
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);

    if ($length <= 125)
        $header = pack(\'CC\', $b1, $length);
    elseif($length > 125 && $length < 65536)$header = pack(\'CCS\', $b1, 126, $length);
    elseif($length >= 65536)
    $header = pack(\'CCN\', $b1, 127, $length);

    return $header.$text;
}
?>

==============================

客户端代码

<html>
<head>
  <meta charset=\"UTF-8\">
</head>
<script>
var socket = new WebSocket(\'wss://domain.name:3000/\');

console.log(\'New socket \');
console.log(socket);
console.log(\'Let`s open \');
// Open the socket
socket.onopen = function(event) {
    console.log(event);
    var msg = \'I am the client.\';
    console.log(\'> \' + msg);
    // Send an initial message
    socket.send(msg);
    // Listen for messages
    socket.onmessage = function(event) {
        console.log(\'< \' + event.data);
    };

    // Listen for socket closes
    socket.onclose = function(event) {
        console.log(\'Client notified socket has closed\', event);
    };

    // To close the socket....
    socket.close()
};

socket.onmessage = function(event) {
  console.log(`[message] Data received from server: ${event.data}`);
};

socket.onclose = function(event) {
  if (event.wasClean) {
    console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
  } else {
    console.log(\'[close] Connection died\');
  }
};

socket.onerror = function(error) {
  console.log(`[error] ${error.message}`);
};
</script>
<body>
<p>Please check the console log of your browser.</p>
</body>
</html>

=============================

    标签: javascript php websocket


    【解决方案1】:

    套接字看起来很复杂。我刚刚找到写于 2012 年的 https://github.com/ghedipunk/PHP-Websockets,并在本周让它与 PHP 8.1 一起工作。

    它似乎运作良好。尽管除了测试之外,我还没有真正使用它来发送和接收。计划让登录打开一个套接字并等待电子邮件确认。我什至建立了一种方法来检查 www-data 和 shell_exec(PHP -v socket.phpsee img below) 的进程以保持套接字打开)

    愿神圣的力量与你同在!

    【讨论】:

      猜你喜欢
      • 2021-10-26
      • 2019-01-13
      • 2012-02-28
      • 1970-01-01
      • 2015-01-17
      • 1970-01-01
      • 2011-12-19
      • 2020-11-06
      相关资源
      最近更新 更多