我在网上搜索了很多,但没有找到有用的线索.
我有一个websocket服务器和一个在我的本地机器上一起运行的Web服务器.
当客户端使用浏览器API’new WebSocket(“ws:// localhost”)’连接到它时,我需要将$_SESSION数据传递给websocket服务器(请求使用反向代理发送到websocket,后者知道它当收到带有“升级”标题的请求时.
关键是客户端成功连接到ws服务器,但我还需要使用HTTP Web服务器设置的$_SESSION变量来恢复其SESSION数据.
其实我的情况是这样的(我正在使用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(); } }
有没有办法用我的实际布局来做到这一点,或者我应该配置apache才能使用
mod_proxy_wstunnel模块?
感谢帮助!!!
正如其他StackOverflow答案所示(
Ratchet without Symfony session,Starting a session within a ratchet websocket connection),无法直接在Apache和Ratchet进程之间共享$_SESSION变量.但是,可以启动与Apache服务器的会话,然后访问Ratchet代码中的会话cookie.
原文链接:https://www.f2er.com/php/240316.htmlApache服务器的index.html启动会话:
<?PHP // Get the session ID. $ses_id = session_id(); if (empty($ses_id)) { session_start(); $ses_id = session_id(); } ?><!DOCTYPE html> ...
Ratchet MessageComponentInterface代码访问会话令牌:
public function onMessage(ConnectionInterface $from,$msg) { $sessionId = $from->WebSocket->request->getCookies()['PHPSESSID']; # Do stuff with the token... }
一旦两个服务器都知道用户的会话令牌,他们就可以使用令牌通过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);