2013-08-09 29 views
7

Mam serwer websocket PHP (https://github.com/lemmingzshadow/php-websocket/).

Gdy użytkownik łączy się, chcę ustawić/uzyskać dane sesji.

Problem polega na tym, że nie mogę używać $_SESSION, ponieważ jeśli to zrobię, zamiast sesji klienta otrzymam sesję mojego serwera websocket.

udało mi się dostać SESSID klientów:

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

Ale teraz nie wiem, jak uzyskać dane sesji związanych z tym SESSID.

+2

Wygląda na to, że potrzebna jest jakaś sesyjna baza danych, która umożliwia udostępnianie sesji między tymi dwoma instancjami. –

+0

@SvenvenV Ale, czy muszę używać własnej bazy danych, czy mogę uzyskać dostęp do bazy danych, w której php zapisuje dane sesji? – Oriol

+0

, aby klient wysłał swój identyfikator sesji przez gniazdo, możesz go użyć do ustawienia identyfikatora w php przed wykonaniem session_start –

Odpowiedz

5

Wydaje mi się rozwiązać go (ale muszę go przetestować więcej):

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

I cookies sesyjne, na mój klient strona index.php

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

Wyjaśnienie

Najpierw używam session_id, aby następująca sesja session_start() dała mi sesję związaną z daną SES SID.

Następnie mogę użyć @session_start(), aby rozpocząć sesję. Trzeba @ ponieważ serwer websocket już się rozpoczęła, więc nie korzystali produkuje:

  • PHP Warning: session_start(): Nie można wysłać plik cookie sesji - headers already sent
  • PHP Warning: session_start(): nie można wysłać ogranicznik pamięci podręcznej sesji - nagłówki już wysłane

Teraz mogę zrobić, co chcę z $_SESSION.

Wreszcie używam session_write_close(), aby zamknąć sesję. Musi on być stosowany, ponieważ:

  • session_id musi być wywołana przed session_start(). Jeśli sesja nie zostanie zamknięta, gdy drugi klient się połączy, sesja będzie już otwarta, więc session_id nie będzie działać.

  • Aby uniknąć blokowania sesji. Jak @Sven powiedział, może istnieć tylko jeden przypadek uruchamiania PHP, który ma dostęp do pliku sesji. Ponieważ skrypt serwera websocket powinien działać przez długi czas, po otwarciu sesji nie można używać sesji w innych skryptach, jeśli jej nie zamykasz.

+0

Dziękuję bardzo, bracie !! :) –

+0

@Oriol Możesz także użyć 'session_start (['read_and_close' => true]);' aby natychmiast zamknąć sesję i uniknąć blokady sesji. – ubomb

+0

@ Oriol Er ... nevermind. To jest to, co twierdzi się robić w dokumentach, ale wygląda na to, że nadal jest otwarty podczas testów. 'session_write_close();' działa jednak w moich testach. – ubomb