First alternative is, of course, AJAX requests. AJAX doesn't have the problems of not being able to quickly and easily access the sessions that WebSockets has. Any sufficiently frequent sample rate is indistinguishable from real time.
Now, to my rather long-winded solution implemented in WebSockets:
The HTTP headers are available to the WebSocket server during the handshake, including the cookies. In the server that you're using, PHP-Websockets, the headers are stored in the $headers property.
For instance:
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"
}
These cookies were generated from
session_start();
$_SESSION['Hi!'] = array('Hello!', 'where' => 'world!');
setcookie('MyCookie', 'My Value;!@#$%', 0, '/', '127.0.0.1', false, true);
setcookie('MyNonhttponlyCookie', 'My Value', 0, '/', '127.0.0.1', false, false);
Thus, the value of $user->headers['cookie'] is a semicolon and space (;) delimited collection of key value pairs, where the values are URL encoded and separated from its key with an equal sign. (PHP complains if you put reserved characters in the cookie name. Thus the cookie key can not contain any url encoded values.)
A quick way to extract these are as follows
$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;!@#$%"
["MyNonhttponlyCookie"]=>
string(8) "My Value"
}
We now have the session ID. Double check with session_name(), which will give you the key of the cookie that actually holds the session ID.
We could serialize and unserialize the session file as stored in the server, which is pointed at by session_save_path()... but I want to cheat.
Because the built-in session system locks the session files, we can't just keep the session file open and constantly watch for changes, nor can we lock the file ourselves for long periods of time.
It would be ideal if we could use the __get() and __set() magic methods here in the same way we'd use the $_SESSION superglobal (such as $myUser->_session['key'] = 'value';), but PHP does not allow treating these methods as arrays. Instead, we have to set a more mundanely named method.
<?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!
}
}
(Note: I'm also pointing my feature request at this question, to base my eventual implementation of cookie parsing and session handling here, so that I can remember my research tonight as I work.)
$headersimplemented as an array. I'll add a thorough answer later (and add a feature request to parse cookies), but that should help get you going in the right direction.