簡體   English   中英

如何從套接字消息(PHP)中獲取 cookies?

[英]How can I get cookies from socket message (PHP)?

我在 PHP 中有一個套接字聊天應用程序腳本。我想對用戶進行身份驗證,但我無法僅在握手時從請求標頭中獲取 cookies。 這是我下面的腳本。 當客戶端發送消息時,如何每次都獲得 cookies? getallheaders function 不起作用,因為它不包括 cookies。socket_recv function 只給我請求的主體。 SocketController 在這種情況下並不重要,它只進行錯誤檢查,並且有一些字段聲明。

<?php namespace Models\Messages;
use Controllers\Messages\SocketController;
use Models\Logs\ErrorLog;
use PDO;

class Socket extends SocketController {

    public function SocketHandler() {

        $this->clientSocketArray = [$this->socketResource];

        while (true) {
            $newSocketArray = $this->clientSocketArray;
            socket_select($newSocketArray, $null, $null, 0, 10);
            
            if (in_array($this->socketResource, $newSocketArray)) {
                $newSocket = socket_accept($this->socketResource);
                $this->clientSocketArray[] = $newSocket;
                $header = socket_read($newSocket, 1024);
                $this->DoHandshake($header, $newSocket, self::HOST, self::PORT);
                
                socket_getpeername($newSocket, $client_ip_address);
                $connectionACK = $this->NewConnectionACK($client_ip_address);
                
                $this->Send($connectionACK);
                
                $newSocketIndex = array_search($this->socketResource, $newSocketArray);
                unset($newSocketArray[$newSocketIndex]);
            }
            
            foreach ($newSocketArray as $newSocketArrayResource) {
                //$headers = apache_request_headers();
                $headers = getallheaders();
                file_put_contents("headers.txt", json_encode($headers), FILE_APPEND);

/*//!!!this is the message sender part!!!, I'd like to get the cookies here*/

                while(socket_recv($newSocketArrayResource, $socketData, 1024, 0) >= 1) {

                    $socketMessage = $this->Unseal($socketData);
                    $messageObj = json_decode($socketMessage, 1);

                    $senderID = isset($messageObj["senderID"]) ? (int)$messageObj["senderID"] : 0;
                    $receiverID = isset($messageObj["receiverID"]) ? (int)$messageObj["receiverID"] : 0;
                    $messageType = isset($messageObj["messageType"]) ? (int)$messageObj["messageType"] : 1;
                    $message = isset($messageObj["message"]) ? $messageObj["message"] : "nincs üzenet";
                    
                    $chat_box_message = $this->CreateChatBoxMessage(
                        $senderID, $receiverID, $messageType, $message
                    );

                    $this->Send($chat_box_message);
                    break 2;
                }
                
                $socketData = @socket_read($newSocketArrayResource, 1024, PHP_NORMAL_READ);
                if ($socketData === false) {
                    socket_getpeername($newSocketArrayResource, $client_ip_address);
                    $connectionACK = $this->ConnectionDisconnectACK($client_ip_address);
                    $this->Send($connectionACK);
                    $newSocketIndex = array_search($newSocketArrayResource, $this->clientSocketArray);
                    unset($this->clientSocketArray[$newSocketIndex]);
                }
            }
        }

        socket_close($this->socketResource);
    }

    function Send($message) {
        // global $clientSocketArray;
        $messageLength = strlen($message);

        foreach($this->clientSocketArray as $clientSocket) {
            @socket_write($clientSocket, $message, $messageLength);
        }

        return true;
    }

    function Unseal($socketData) {
        $length = ord($socketData[1]) & 127;
        if($length == 126) {
            $masks = substr($socketData, 4, 4);
            $data = substr($socketData, 8);
        }
        else if($length == 127) {
            $masks = substr($socketData, 10, 4);
            $data = substr($socketData, 14);
        }
        else {
            $masks = substr($socketData, 2, 4);
            $data = substr($socketData, 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', $b1, 126, $length);
        elseif($length >= 65536)
            $header = pack('CCNN', $b1, 127, $length);
        return $header.$socketData;
    }

    function DoHandshake($receivedHeader, $clientSocketResource, $hostName, $port) {
        $headers = array();
        $lines = preg_split("/\r\n/", $receivedHeader);
        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: {$hostName}/maganoktatas\r\n" .
        "WebSocket-Location: ws://$hostName:$port/maganoktatas/app/ajax/sockeg_messages.php\r\n".
        "Sec-WebSocket-Accept:$secAccept\r\n\r\n";
        socket_write($clientSocketResource, $buffer, strlen($buffer));
    }
    
    function NewConnectionACK($clientIP) {
        $message = 'New client ' . $clientIP.' joined';

        $messageArray = [
            "messageType"=>5,
            "message"=>$message
        ];

        $ACK = $this->Seal(json_encode($messageArray));
        return $ACK;
    }
    
    function ConnectionDisconnectACK($clientIP) {
        $message = 'Client ' . $clientIP.' disconnected';

        $messageArray = [
            "messageType"=>5,
            "message"=>$message
        ];
        
        $ACK = $this->Seal(json_encode($messageArray));
        return $ACK;
    }
    
    public function GetUserName(string $friendID):string {
        $stmt = $this->conn->prepare("SELECT CONCAT(LastName, ' ' , FirstName) as FullName
        FROM users WHERE UserID = ?");
        $stmt->execute([
            $friendID
        ]);

        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        return isset($row["FullName"]) ? $row["FullName"] : "";
    }
    
    function CreateChatBoxMessage(int $senderID, int $receiverID, int $messageType, 
    string $message):string {

        $messageArray = [
            "messageType"=>$messageType,
            "message"=>htmlspecialchars($message),
            "receiverID"=>$receiverID,
            "senderID"=>$senderID, 
            "senderName"=>$this->GetUserName($senderID)
        ];

        $chatMessage = $this->Seal(json_encode($messageArray));
        return $chatMessage;
    }

    function __destruct() {
        //
    }
}
?>

你不能也不需要。 當通過 http 協議建立連接時,瀏覽器僅在握手期間發送 cookie。 握手后,協議從 http 更改為 websocket。您的客戶端通過 tcp 連接連接,因此當客戶端發送消息時,您已經知道這條消息來自誰。 在接受連接后,只需將您的客戶端數據(id、登錄名或其他)與套接字處理程序一起保存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM