I have a PHP websocket server (https://github.com/lemmingzshadow/php-websocket/).
When an user connects, I want to set/get some session data.
The problem is that I can't use $_SESSION
because if I do that, instead of clients' session I get the session of my websocket server.
I have managed to get clients' SESSID:
private function handshake($data) {
$this->log('Performing handshake');
if(preg_match("/PHPSESSID=(.*?)(?:;|\r\n)/", $data, $matches)){
$sessid = $matches[1];
}
/* Do handshake */
}
But now I don't know how to get the session data related to that SESSID.
It seems I have solved it (but I have to test it more):
private function handshake($data) {
$this->log('Performing handshake');
if(preg_match("/PHPSESSID=(.*?)(?:;|\r\n)/", $data, $matches)){
$this->sessID = $matches[1];
session_id($this->sessID);
@session_start();
if(isset($_SESSION['userName'])){
$this->userName = $_SESSION['userName'];
}else{
$_SESSION['userName'] = $this->userName;
}
session_write_close();
}else{
$this->log('No SESSID');
return false;
}
/* Do handshake */
}
And to enable session cookies, on my client page index.php
<?php
session_start();
?>
<!DOCTYPE html>
<!-- Page's HTML -->
Explanation
First, I use session_id
so that the following session_start()
will give me the session related to the given SESSID.
Then, I can use @session_start()
to start the session. It needs @
because the websocket server has already started, so not using it produces:
- PHP Warning: session_start(): Cannot send session cookie - headers already sent
- PHP Warning: session_start(): Cannot send session cache limiter - headers already sent
Now I can do what I want with $_SESSION
.
Finally, I use session_write_close()
in order to close the session. It must be used because:
session_id
must be called before session_start()
. If the session isn't closed, when a second client connects, a session will be already open, so session_id
won't work.
To avoid session locking. As @Sven said, there can only be one instance of PHP running that has access to the session file. Since the websocket server's script should be running for a long time, once it opens a session, you can't use session in other scripts if you don't close it.