2013-08-09 27 views
7

Ho un server websocket PHP (https://github.com/lemmingzshadow/php-websocket/).

Quando un utente si connette, desidero impostare/recuperare alcuni dati di sessione.

Il problema è che non posso usare $_SESSION perché se lo faccio, invece della sessione dei client ottengo la sessione del mio server websocket.

Sono riuscito a ottenere SESSID clienti:

private function handshake($data) { 
    $this->log('Performing handshake'); 
    if(preg_match("/PHPSESSID=(.*?)(?:;|\r\n)/", $data, $matches)){ 
     $sessid = $matches[1]; 
    } 
    /* Do handshake */ 
} 

Ma ora non so come ottenere i dati di sessione relativi a tale SESSID.

+2

Sembra che tu abbia bisogno di una sorta di database di sessione che ti permetta di condividere sessioni tra le due istanze. –

+0

@StevenV Ma, devo usare il mio db, o posso accedere al db dove php salva i dati della sessione? – Oriol

+0

fare in modo che il client invii il proprio ID di sessione sul socket, quindi è possibile utilizzarlo per impostare l'ID in php prima di fare session_start –

risposta

5

Sembra che io abbia risolto (ma devo provare più):

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 */ 
} 

E abilitare i cookie di sessione, il mio cliente pagina index.php

<?php 
session_start(); 
?> 
<!DOCTYPE html> 
<!-- Page's HTML --> 

Spiegazione

In primo luogo, io uso session_id in modo che il seguente session_start() mi dia la sessione relativa al SES dato SID.

Quindi, è possibile utilizzare @session_start() per avviare la sessione. Ha bisogno @ perché il server websocket è già iniziata, quindi non lo si utilizza produce:

  • PHP Warning: session_start(): Non è possibile inviare cookie di sessione - headers already sent
  • PHP Warning: session_start(): Non è possibile inviare limitatore della cache di sessione - intestazioni già inviate

Ora posso fare quello che voglio con $_SESSION.

Infine, io uso session_write_close() per chiudere la sessione. Deve essere utilizzato perché:

  • session_id deve essere chiamato prima session_start(). Se la sessione non viene chiusa, quando un secondo client si connette, una sessione sarà già aperta, quindi session_id non funzionerà.

  • Per evitare il blocco della sessione. Come ha detto @Sven, può esserci solo un'istanza di PHP in esecuzione che abbia accesso al file di sessione. Poiché lo script del server Websocket deve essere in esecuzione per un lungo periodo di tempo, una volta aperta una sessione, non è possibile utilizzare la sessione in altri script se non la si chiude.

+0

Grazie mille fratello !! :) –

+0

@Oriol Puoi anche usare 'session_start (['read_and_close' => true]);' per chiudere immediatamente la sessione ed evitare il blocco della sessione. – ubomb

+0

@Oriol Er ... non importa. Questo è ciò che afferma di fare nei documenti, ma sembra che continui a tenerlo aperto durante i test. 'session_write_close();' comunque funziona nel mio test. – ubomb