如何通过$ _SESSION变量到WebSocket的服务器? [英] How to pass $_SESSION variables to a websocket server?

查看:399
本文介绍了如何通过$ _SESSION变量到WebSocket的服务器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在网上搜索了很多,但没有找到有用的线索。

I have searched a lot on the web but didn't find a useful clue.

我有一个WebSocket伺服器和Web服务器我的本地机器上同时运行。

I have a websocket server and a web server running together on my local machine.

我需要$ _SESSION数据传递到WebSocket伺服器当客户端使用浏览器API新的WebSocket(WS:// localhost的)'连接到它(请求使用反向代理发送到WebSocket的,当与一个'升级'头接收请求)知道这一点。

I need to pass $_SESSION data to the websocket server when a client connects to it using the browser API 'new WebSocket("ws://localhost")' (the request is send to the websocket using a reverse proxy, which knows it when receives requests with an 'Upgrade' header).

问题的关键是,客户端成功连接到服务器WS,但我需要使用由HTTP Web服务器设置好的了$ _SESSION变量也恢复他们的会话数据。

The point is that the clients successfully connect to the ws server, but I need to recover also their SESSION data using the $_SESSION variables setted by the HTTP web server.

其实我的情况是这样的(我用的棘轮库):

Actually my situation is this (I am using the Ratchet library):

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是很简单的:

The MyAppClass is very simple:

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

有没有办法做到这一点与我的实际的布局或者我应该要使用Apache的配置
mod_proxy_wstunnel模块?

Is there a way to do that with my actual layout or should I configure apache in order to use mod_proxy_wstunnel module?

感谢您的帮助!

推荐答案

至于其他StackOverflow的答案显示(棘轮没有Symfony的会议,<一个href=\"http://stackoverflow.com/questions/16183917/starting-a-session-within-a-ratchet-websocket-connection\">Starting棘轮WebSocket连接内的会话),有没有办法直接分享Apache和棘轮过程之间的$ _SESSION变量。这是可能的,但是,启动与Apache服务器的会话,然后将棘轮code内访问会话cookie。

As other StackOverflow answers show (Ratchet without Symfony session, Starting a session within a ratchet websocket connection), there is no way to directly share the $_SESSION variable between Apache and the Ratchet process. It is possible, however, to start a session with the Apache server and then access the session cookie within the Ratchet code.

Apache服务器的index.html的启动会话:

Apache server's index.html starts the session:

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

棘轮MessageComponentInterface code访问会话令牌:

Ratchet MessageComponentInterface code accesses the session token:

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

在两个服务器知道用户的会话令牌,他们可以使用该令牌通过MySQL数据库共享信息(这是我做的):

Once both servers know the user's session token, they can use the token to share information through a MySQL database (which is what I do):

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

另外,你可以做的进程间通信的更奇特的形式:

Alternatively, you could do a more exotic form of inter-process communication:

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

这篇关于如何通过$ _SESSION变量到WebSocket的服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆