微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PHP Websocker 多客户端问题

如何解决PHP Websocker 多客户端问题

我使用教程中的代码片段创建了一个 websocket 服务器,但是我遇到了一个问题,当我连接更多客户端时,出现错误并且无法连接其他客户端。

代码如下:

<?PHP

set_time_limit(0);

// Server-Konfiguration
define('HOST_NAME',"74.119.136.210"); 
define('PORT',"8090");
$null = NULL;
    
$socketResource = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_set_option($socketResource,SOL_SOCKET,SO_REUSEADDR,1);
socket_bind($socketResource,PORT);
socket_listen($socketResource);

$clientSocketArray = array($socketResource);

require_once "d68948613b56584bc4fad01121fc51412e254423/socket_netzaufbau.PHP";
require_once __DIR__."/../netzaufbau.amperify.de/public/scripts/measurement/measurement_calculate.PHP";
                    
while (true) {
    
    $newSocketArray = $clientSocketArray;
    socket_select($newSocketArray,$null,10);
    
    if (in_array($socketResource,$newSocketArray)) {
        
        $newSocket = socket_accept($socketResource);
        $clientSocketArray[] = $newSocket;
        
        $header = socket_read($newSocket,1024);
        
        // send Header
        $headers = array();
        $lines = preg_split("/\r\n/",$header);
        foreach($lines as $line)
        {
            $line = chop($line);
            if(preg_match('/\A(\S+): (.*)\z/',$line,$matches))
            {
                $headers[$matches[1]] = $matches[2];
            }
        }

        $secKey = $headers['Sec-WebSocket-Key'];
        $secAccept = base64_encode(pack('H*',sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
        $buffer  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
        "Upgrade: websocket\r\n" .
        "Connection: Upgrade\r\n" .
        "WebSocket-Origin: ".HOST_NAME."\r\n" .
        "WebSocket-Location: ws://".HOST_NAME.":".PORT."/server.PHP\r\n".
        "Sec-WebSocket-Accept:$secAccept\r\n\r\n";
        socket_write($newSocket,$buffer,strlen($buffer));
        
        socket_getpeername($newSocket,$client_ip_address);
        
        // Neue Verbindung aufbauen + Text generieren
        $messageArray = array('connection' => "true");
        $ACK = seal(json_encode($messageArray));
        
        // Senden der Nachricht
        send($ACK);
        
        $newSocketIndex = array_search($socketResource,$newSocketArray);
        unset($newSocketArray[$newSocketIndex]);
    }
    
    foreach ($newSocketArray as $newSocketArrayResource) {  
        
        while(socket_recv($newSocketArrayResource,$socketData,1024,0) >= 1){
            $socketMessage = unseal($socketData);
            $messageObj = json_decode($socketMessage);
            
            // Umwandeln der empfangenen Daten von Objekt in Array
             if (is_object($messageObj)) {
                $vars = get_object_vars($messageObj);
                
                if(!isset($vars['projectID'])){
                    $vars['projectID'] = "";
                }
                
                // Projekt Netzaufbau Datenabfrage mit Key
                if($vars['projectID'] == "d68948613b56584bc4fad01121fc51412e254423"){
                        MeasurementLoader::calculate();
                    $msg = Netzaufbau::receiveData();
                }else{
                    $msg = "Error";
                }
                
             }
            
            $ACK = seal(json_encode($msg));
            send($ACK);
            break 2;
        }
        
        $socketData = @socket_read($newSocketArrayResource,PHP_norMAL_READ);
        
        if ($socketData === false) { 
            socket_getpeername($newSocketArrayResource,$client_ip_address);
            
            $messageArray = array('connection' => "false");
            $ACK = seal(json_encode($messageArray));
        
            send($ACK);
            $newSocketIndex = array_search($newSocketArrayResource,$clientSocketArray);
            unset($clientSocketArray[$newSocketIndex]);             
        }
        
    }
}

socket_close($socketResource);  

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

function seal($socketData) {
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($socketData);
    
    if($length <= 125)
        $header = pack('CC',$b1,$length);
    elseif($length > 125 && $length < 65536)
        $header = pack('CCn',126,$length);
    elseif($length >= 65536){
        $upper_32_bits = $length >> 32;
         $lower_32_bits = $length & 0xffffffff;
         $header = pack('CCNN',127,$upper_32_bits,$lower_32_bits); 
         }
    return $header.$socketData;
}
    
    
function send($message) {
    global $clientSocketArray;
    $sx = strlen($message);
    foreach($clientSocketArray as $clientSocket)
    {
        @socket_write($clientSocket,$message,$sx);
    }
    return true;
}
    
?>

在我的服务器上,我使用命令 sudo PHP /path/to/server.PHP 但收到以下错误

[2021 年 5 月 27 日星期四 06:09:38.839524] [proxy_wstunnel:error] [pid 3418] [客户178.
19.239.28:50163] AH02452:无法连接到后端:socket.amperify。

[2021 年 5 月 27 日星期四 00:02:44.086047] [代理:错误] [pid 3419] (111)连接拒绝
ed: AH00957: WS: 尝试连接到 75.119.136.210:8090 (socket.amperify.de)
失败

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?