3
votes

I have looked at several tutorials and looked at the Symfony, and Ratchet API documents but I can't get the session data in my Chat class (WebSocket server Application).

I set the session data when the user hits the web page:

<?php
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcacheSessionHandler;

require 'vendor/autoload.php';

$memcache = new Memcache;
$memcache->connect('127.0.0.1', 11211);

$storage = new NativeSessionStorage(
    array(),
    new MemcacheSessionHandler($memcache)
);
$session = new Session($storage);
$session->start();
$session->set('id', $user_id);

print_r($session->all());
# Array ( [id] => 1 )

I start the WebSocket server by command line (php ./server.php):

<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Ratchet\Session\SessionProvider;
use Symfony\Component\HttpFoundation\Session\Storage\Handler;
use MyApp\Chat;

$ip = "127.0.0.1";
$port = "8080";

# Change the directory to where this cron script is located.
chdir(dirname(__FILE__));

# Get database connection.
require_once '../../includes/config.php';
require_once '../../vendor/autoload.php';

$memcache = new Memcache;
$memcache->connect($ip, 11211);

$session = new SessionProvider(
    new Chat,
    new Handler\MemcacheSessionHandler($memcache)
);

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            $session
        )
    ),
    $port,
    $ip
);
$server->run();

In my MyApp\Chat application, I try to get the session data I set but it returns NULL:

<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface
{
    protected $clients;
    private $dbh;

    public function __construct()
    {
        global $dbh;
        $this->clients=array();
        $this->dbh=$dbh;
    }

    public function onOpen(ConnectionInterface $conn)
    {
        $this->clients[$conn->resourceId] = $conn;
        echo "New connection! ({$conn->resourceId})\n";

        print_r($conn->Session->get('name'));
        # NULL
    }
}
1
Is the websocket runing on the same hostname. Sessions work off cookies and if the websocket and the website are on two different domains then the session cookie won't be sent on the websocket request. E.g. 127.0.0.1 and localhost are considered differentMarshallOfSound
@MarshallOfSound Thank you. I had seen that written before, but for some reason I had forgotten about that, which I should have realized to begin with. I changed the WebSocket Server host to my domain (example.dev) instead of 127.0.0.1. Seems like I can keep the memcache connect to the local IP though.Draven
Glad I could help, I'll post it as an answer later so people can find it if they have the same issueMarshallOfSound

1 Answers

2
votes

In order for sessions to be passed between services like that they must be hosted on the same domain. This is because sessions are managed through cookies and the cookies are fixed to a specific domain.

In this case your domains are different, one appears to be hosted on "hostname" and the other on "127.0.0.1". When it is set up like this your cookies won't be sent to both hosts.

You can fix this by setting up your WebSocket on "hostname" instead of "127.0.0.1". Then it should just work :)