[英]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.