如何将socket_read值获取为从PHP websocket中的javascript发送的纯文本

Posted

技术标签:

【中文标题】如何将socket_read值获取为从PHP websocket中的javascript发送的纯文本【英文标题】:how to get socket_read value to plain text sent from javascript in PHP websocket 【发布时间】:2021-01-09 16:00:12 【问题描述】:

我正在尝试制作我的小型 websocket php 类,我想在其中制作诸如 onopen onmessage 之类的功能,例如 node js [我知道那里还有其他库,但我想自己学习它]。到目前为止我能够使用下面的代码成功接收从 js websocket 到 php 的消息

<?php 
$host = "localhost";
$port = 8001;
$sockets=array();

function sendAll($connections,$msg)
    foreach ($connections as $each) 
        send($each,$msg);
    


function send($client,$msg)
    $msg = chr(129) . chr(strlen($msg)) . $msg;
    socket_write($client,$msg,strlen($msg));



function handshake($client)
    $request = socket_read($client, 5000);
    preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $request, $matches);
    $key = base64_encode(pack(
        'H*',
        sha1($matches[1] . '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-Version: 13\r\n";
    $headers .= "Sec-WebSocket-Accept: $key\r\n\r\n";
    socket_write($client, $headers, strlen($headers));


// Create WebSocket.
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
socket_set_nonblock($server);
socket_bind($server, $host, $port);
socket_listen($server);    


while(true)

    $client = socket_accept($server);
    if($client != false)
        usleep(100);
        handshake($client);
        array_push($sockets,$client);
        print_r($sockets); 
    
    else
        if(count($sockets) > 0)
            foreach ($sockets as $each) 
                $msg = socket_read($each,5000);
                if($msg != false)
                    filter($msg);
                    // send($each,"testing");
                
            
        
    






function filter($msg)
    $msg = unpack("c*",$msg);
    foreach ($msg as $value) 
        echo chr($value);
    
    // print_r($msg);

?>

经过一些研究,我发现 websocket 以二进制形式发送消息。我无法将该消息转换为纯文本。我不知道数据发送到哪种语言或格式。请告诉我它是哪种格式以及如何将其读取为下面的纯文本示例图片

【问题讨论】:

【参考方案1】:

我终于找到了从this website解码的方法

它实际上被屏蔽了,需要被取消屏蔽。在这里,我从网站上找到了一个功能,我所要做的就是阅读带有以下自定义功能的标记文本被取消屏蔽

function unmask($text) 
    $length = ord($text[1]) & 127;
    if($length == 126) 
    $masks = substr($text, 4, 4);
    $data = substr($text, 8);
    
    elseif($length == 127) 
    $masks = substr($text, 10, 4);
    $data = substr($text, 14);
    
    else 
    $masks = substr($text, 2, 4);
    $data = substr($text, 6);
    
    $text = "";
    for ($i = 0; $i < strlen($data); ++$i) 
    $text .= $data[$i] ^ $masks[$i%4];
    
    return $text;
    

【讨论】:

以上是关于如何将socket_read值获取为从PHP websocket中的javascript发送的纯文本的主要内容,如果未能解决你的问题,请参考以下文章

如何将变量的值设置为从 Alamofire 收到的数据?

PHP socket_read 等待数据读取

获取从日期到月底 PHP 的秒数

SQL(雅典娜)中的取消嵌套:如何将结构数组转换为从结构中提取的值数组?

如何将引导模式内的下拉列表的选定值获取到php中的文本框中

如何在 Laravel 中重定向后设置选择值