2014-04-22 10 views
5

Ich habe viel im Web gesucht, aber nicht einen nützlichen Anhaltspunkt finden.

Ich habe einen WebSocket-Server und einen Web-Server zusammen auf meinem lokalen Rechner ausgeführt wird.

Ich muss $ _SESSION-Daten an den Websocket-Server übergeben, wenn ein Client eine Verbindung mit dem neuen WebSocket der Browser-API ("ws: // localhost") herstellt (die Anfrage wird über einen Reverse-Proxy an den Websocket gesendet) , die es weiß, wenn Anfragen mit einem 'Upgrade' Header empfangen werden.

Der Punkt ist, dass die Clients erfolgreich eine Verbindung zum WS-Server herstellen, aber ich muss auch ihre SESSION-Daten mit den $ _SESSION-Variablen wiederherstellen, die vom HTTP-Webserver eingestellt wurden.

Eigentlich ist meine Situation dies (ich die Ratsche Bibliothek bin mit):

use Ratchet\Server\IoServer; 
use Ratchet\Http\HttpServer; 
use Ratchet\WebSocket\WsServer; 
use MyApp\MyAppClassChat; 

require dirname(__DIR__) . '/vendor/autoload.php'; 

$server = IoServer::factory(new HttpServer(new WsServer(new MyAppClass())), 8080); 
$server->run(); 

Die MyAppClass ist sehr einfach:

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

class MyAppClass implements MessageComponentInterface { 

    protected $clients; 

    public function __construct() { 
     $this->clients = new \SplObjectStorage; 
    } 

    public function onOpen(ConnectionInterface $conn) { 
      /* I would like to put recover the session infos of the clients here 
       but the session_start() call returns an empty array ($_SESSION variables have been previuosly set by the web server)*/ 
     session_start(); 
     var_dump($_SESSION) // empty array... 
     echo "New connection! ({$conn->resourceId})\n"; 
    } 

    public function onMessage(ConnectionInterface $from, $msg) { 
     $numberOfReceivers = count($this->clients) -1; 
     echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n", $from->resourceId, $msg, 
           $numberOfReceivers, $numberOfReceivers == 1 ? '' : 's'); 

     $this->clients->rewind(); 
     while ($this->clients->valid()) 
     { 
      $client = $this->clients->current(); 
      if ($client !== $from) { 
       $client->send($msg); 
      } 
      $this->clients->next(); 
     } 
    } 

    public function onClose(ConnectionInterface $conn) { 
     $this->clients->detach($conn); 
     echo "Connection {$conn->resourceId} has disconnected\n"; 
    } 

    public function onError(ConnectionInterface $conn, \Exception $e) { 
     echo "An error has occurred: {$e->getMessage()}\n"; 
     $conn->close(); 
    } 
} 

Gibt es eine Möglichkeit, dass mit meinem aktuellen Layout zu tun oder sollte ich apache um mod_proxy_wstunnel Modul zu verwenden, konfigurieren?

Dank für die Hilfe !!!

Antwort

8

Wie andere StackOverflow-Antworten zeigen (Ratchet without Symfony session, Starting a session within a ratchet websocket connection), gibt es keine Möglichkeit, die $ _SESSION-Variable zwischen Apache und dem Ratchet-Prozess direkt zu teilen. Es ist jedoch möglich, eine Sitzung mit dem Apache-Server zu starten und dann auf den Sitzungscookie innerhalb des Ratchet-Codes zuzugreifen.

index.html des Apache-Servers startet die Sitzung:

<?php 
// Get the session ID. 
$ses_id = session_id(); 
if (empty($ses_id)) { 
    session_start(); 
    $ses_id = session_id(); 
} 
?><!DOCTYPE html> ... 

Ratchet MessageComponentInterface Code, um die Session-Token zugreift:

public function onMessage(ConnectionInterface $from, $msg) { 
    $sessionId = $from->WebSocket->request->getCookies()['PHPSESSID']; 
    # Do stuff with the token... 
} 

Sobald beide Server die Sitzung des Benutzers Token wissen, sie das Token verwenden Informationen über eine MySQL-Datenbank teilen (was ich tue):

# Access session data from a database: 
    $stmt = $this->mysqli->prepare("SELECT * FROM users WHERE cookie=?"); 
    $stmt->bind_param('s', $sessionId); 
    $stmt->execute(); 
    $result = $stmt->get_result(); 
Alternativ

, könnten Sie eine exotische Form der Interprozesskommunikation tun: „mit Cookie Apache-Prozess über den Benutzer fragen“

# Ratchet server: 
    $opts = array(
     'http'=>array(
      'method'=>'GET', 
      'header'=>"Cookie: PHPSESSID=$sessionId\r\n" 
     ) 
    ); 
    $context = stream_context_create($opts); 
    $json = file_get_contents('http://localhost:80/get_session_info.php', false, $context); 
    $session_data = json_decode($json); 

    # Apache server's get_session_info.php 
    # Note: restrict access to this path so that remote users can't dump 
    # their own session data. 
    echo json_encode($_SESSION); 
+0

Wirklich smart, aber was meinst du wie kannst du das erreichen? Ich meine, wenn ich nicht über eine DB für Sitzungen verwenden, muss ich irgendwie das WebSocket-Server machen PHP bitten, die Sitzung des aktuellen Senders mit der Session-ID abzurufen. Ich nehme an, dass dies der falsche Weg wäre, habe ich recht? 'öffentliche Funktion onMessage (ConnectionInterface $ von, $ msg) { $ sessionId = $ von-> WebSocket-> Anfrage-> getCookies() ['PHPSESSID']; Sitzungs-ID ($ Sitzungs-ID); session_start(); echo $ _SESSION ['somekey]]; } ' Ist das zuverlässig? – tonix

+0

Ich glaube nicht, dass Sie session_start() innerhalb des Websocket-Servers aufrufen können; Nur der Apache-Server kann das Sitzungstoken festlegen, da der Set-Cookie-Befehl in den Header der Webseite gehen muss. Sobald beide Server über das Sitzungstoken verfügen, liegt es an Ihnen, wie Sie die Kommunikationssitzungsdaten mithilfe des Sitzungstokens verarbeiten möchten.Da Apache und Ratchet beide Server sind, können Sie die Daten von einem Prozess zum anderen "bedienen", indem Sie sich selbst abschaben. – dmiller309

+0

Entschuldigung, ich habe nicht verstanden, ich habe verstanden, dass ich sesssion_start() nicht verwenden kann, wie ich vermutete, aber Apache und Ratchet miteinander kommunizieren zu lassen, was soll ich dann implementieren? Ein Web Service, der von Ratchet aufgerufen und an Apache adressiert wird, um die richtigen Daten basierend auf der Sitzungskennung zu erhalten oder was? Vielen Dank für Ihre Aufmerksamkeit und Ihr Interesse! – tonix

Verwandte Themen