Первой альтернативой является, конечно, AJAX запросы. У AJAX нет проблем с тем, что вы не можете быстро и легко получить доступ к сеансам, которые есть в WebSockets. Любая достаточно частая частота дискретизации неотличима от реального времени.
Теперь, к моему довольно многословно внедренным в WebSockets:
Заголовки HTTP доступны серверу WebSocket во время рукопожатия, в том числе печенье. На сервере, который вы используете, PHP-Websockets, заголовки хранятся в свойстве $headers
.
Например:
var_dump($user->headers);
array(14) {
["get"]=>
string(8) "/echobot"
["host"]=>
string(14) "127.0.0.1:9000"
...snip...
["cookie"]=>
string(100) "PHPSESSID=jan9uknpc06mk4ddghph4870t1; MyCookie=My+Value%21%40%23%24%25; MyNonhttponlyCookie=My+Value"
}
Эти файлы были сгенерированы из
session_start();
$_SESSION['Hi!'] = array('Hello!', 'where' => 'world!');
setcookie('MyCookie', 'My Value;[email protected]#$%', 0, '/', '127.0.0.1', false, true);
setcookie('MyNonhttponlyCookie', 'My Value', 0, '/', '127.0.0.1', false, false);
Таким образом, значение $user->headers['cookie']
является точкой с запятой, и пространство (;
), ограниченный сбор ключевых пар значений, где значения кодируются URL и отделяются от его ключа знаком равенства. (PHP жалуется, если вы поставите зарезервированные символы в имени куки. Таким образом, ключ куки не может содержать URL-адрес закодированные значения.)
Быстрый способ извлечь эти следующие
$cookies = array();
$cookiesParts = explode('; ', $user->headers['cookie']);
foreach ($cookiesParts as $cookieParts) {
$interimCookie = explode('=', $cookieParts);
$cookies[$interimCookie[0]] = urldecode($interimCookie[1]);
}
var_dump($cookies);
array(3) {
["PHPSESSID"]=>
string(26) "jan9uknpc06mk4ddghph4870t1"
["MyCookie"]=>
string(14) "My Value;[email protected]#$%"
["MyNonhttponlyCookie"]=>
string(8) "My Value"
}
Теперь у нас есть идентификатор сессии. Двойная проверка с session_name()
, которая даст вам ключ от файла cookie, который фактически содержит идентификатор сеанса.
Мы могли бы сериализовать и несериализировать файл сеанса, хранящийся на сервере, на который указывает session_save_path()
... но я хочу обмануть.
Поскольку встроенная система сеанса блокирует файлы сеанса, мы не можем просто открывать файл сеанса и постоянно следить за изменениями, а также не можем сами фиксировать файл в течение длительных периодов времени.
Было бы идеально, если бы мы могли использовать __get()
и __set()
магические методы здесь таким же образом, мы будем использовать $_SESSION
суперглобальном (например, $myUser->_session['key'] = 'value';
), но PHP не позволяет обрабатывать эти методы как массивы. Вместо этого мы должны установить более простой метод.
<?php
class MyUser extends WebSocketUser {
public $session_id; // gets set somewhere. Good place is probably is your implementation of the `connected($user)` abstract method.
public getSession($key) {
session_id($this->session_id);
session_start();
$val = $_SESSION[$key];
session_write_close(); // very important!
return $val;
}
public setSession($key, $value) {
session_id($this->session_id);
session_start();
$_SESSION[$key] = value;
session_write_close(); // still very important!
}
}
(Примечание. Я также указывая мой feature request в этом вопросе, чтобы основывать свое окончательное осуществление печенья разбора и обработки здесь сессии, так что я помню свое исследование сегодня, как я работаю)
Заголовки HTTP, включая файлы cookie, доступны для сервера WS во время рукопожатия. На этом конкретном сервере заголовки доступны в пользовательском классе под свойством '$ headers', реализованным в виде массива. Я добавлю подробный ответ позже (и добавлю запрос функции для анализа файлов cookie), но это должно помочь вам двигаться в правильном направлении. – Ghedipunk