2014-04-22 6 views
5

मैंने वेब पर बहुत कुछ खोजा है लेकिन एक उपयोगी सुराग नहीं मिला।

मैं एक WebSocket सर्वर और वेब सर्वर के अपने स्थानीय मशीन पर एक साथ चल रहा है।

जब ब्राउज़र क्लाइंट एपीआई 'नई वेबसॉकेट ("ws: // localhost")' का उपयोग कर कनेक्ट करता है तो मुझे वेबसाईट सर्वर पर $ _SESSION डेटा पास करने की आवश्यकता होती है (अनुरोध एक रिवर्स प्रॉक्सी का उपयोग करके वेबसाकेट को भेजता है , जो इसे 'अपग्रेड' हेडर के साथ अनुरोध प्राप्त करते समय जानता है)।

मुद्दा यह है कि ग्राहकों को सफलतापूर्वक ws सर्वर से कनेक्ट है, लेकिन मैं $ _SESSION चर HTTP वेब सर्वर द्वारा setted का उपयोग कर भी अपने सत्र डेटा को ठीक करने की जरूरत है।

असल में मेरी स्थिति है यह (मैं Ratchet पुस्तकालय का उपयोग कर रहा):

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(); 

MyAppClass बहुत सरल है:

<?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(); 
    } 
} 

वहाँ ऐसा करने के लिए अपने वास्तविक लेआउट या के साथ एक रास्ता है क्या मुझे mod_proxy_wstunnel मॉड्यूल का उपयोग करने के लिए अपाचे को कॉन्फ़िगर करना चाहिए?

मदद के लिए धन्यवाद !!!

उत्तर

8

के रूप में अन्य StackOverflow जवाब दिखाने (Ratchet without Symfony session, Starting a session within a ratchet websocket connection), वहाँ सीधे अपाचे और Ratchet प्रक्रिया के बीच $ _SESSION चर साझा करने के लिए कोई रास्ता नहीं है। हालांकि, यह अपाचे सर्वर के साथ एक सत्र शुरू करने के लिए संभव है और फिर रैचेट कोड के भीतर सत्र कुकी तक पहुंचें।

अपाचे सर्वर के index.html सत्र शुरू होता है:

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

एक बार दोनों सर्वर उपयोगकर्ता के सत्र टोकन पता है, वे करने के लिए टोकन का उपयोग कर सकते हैं:

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

Ratchet MessageComponentInterface कोड सत्र टोकन तक पहुँचता है एक MySQL डेटाबेस के माध्यम से जानकारी साझा करें (जो मैं करता हूं):

# 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(); 

वैकल्पिक रूप से, आप अंतर संचार प्रक्रिया का एक और अधिक विदेशी प्रपत्र कर सकता है: "कुकी के साथ उपयोगकर्ता के बारे में अपाचे प्रक्रिया पूछते हैं"

# 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

सच स्मार्ट है, लेकिन आप क्या मतलब है आप इसे कैसे प्राप्त कर सकते हैं? मेरा मतलब है, अगर मैं सत्रों के लिए डीबी का उपयोग नहीं करता हूं, तो मुझे किसी भी तरह से WebSocket सर्वर को सत्र आईडी का उपयोग कर वर्तमान प्रेषक के सत्र को पुनर्प्राप्त करने के लिए PHP से पूछने की आवश्यकता है। मुझे लगता है कि यह गलत तरीका होगा, क्या मैं सही हूँ? 'सार्वजनिक समारोह onMessage (ConnectionInterface, $ संदेश से $) { $ sessionId = $ from-> WebSocket-> अनुरोध> getCookies() [ 'PHPSESSID']; session_id ($ sessionId); session_start(); echo $ _SESSION ['somekey']; } ' क्या यह विश्वसनीय है? – tonix

+0

मुझे नहीं लगता कि आप websocket सर्वर के अंदर session_start() को कॉल कर सकते हैं; केवल अपाचे सर्वर सत्र टोकन सेट कर सकता है क्योंकि सेट कुकी कमांड को वेबपृष्ठ के शीर्षलेख में जाना है। एक बार दोनों सर्वरों के पास सत्र टोकन होता है, तो यह आपके ऊपर निर्भर करता है कि आप सत्र टोकन का उपयोग करके सत्र डेटा संचारित करने के तरीके को कैसे संसाधित करना चाहते हैं।चूंकि अपाचे और रैचेट दोनों सर्वर हैं, इसलिए आप स्वयं को स्क्रैप करके डेटा को एक प्रक्रिया से दूसरे में "सेवा" कर सकते हैं। – dmiller309

+0

क्षमा करें मुझे समझ में नहीं आया, मुझे समझ में आया कि मैं sesssion_start() का उपयोग नहीं कर सकता जैसा कि मैंने माना था, लेकिन अपाचे और रैचेट एक-दूसरे को एक-दूसरे से संवाद करने के लिए मुझे क्या लागू करना चाहिए? सत्र पहचानकर्ता के आधार पर उचित डेटा प्राप्त करने के लिए रैकेट से एक वेब सेवा जिसे अपाचे से संबोधित किया जाता है और अपाचे से संबोधित किया जाता है? आपके ध्यान और रुचि के लिए धन्यवाद! – tonix

संबंधित मुद्दे