Php 如何将$\u会话变量传递给websocket服务器?
我在网上搜索了很多,但没有找到有用的线索 我有一个websocket服务器和一个web服务器在本地机器上一起运行 当客户端使用浏览器API“new websocket(“ws://localhost”)”连接到websocket服务器时,我需要将$_会话数据传递到websocket服务器(请求使用反向代理发送到websocket,当接收到带有“Upgrade”头的请求时,反向代理会知道它) 关键是客户端成功地连接到ws-server,但我还需要使用HTTP web服务器设置的$u会话变量恢复它们的会话数据 实际上我的情况是这样的(我正在使用棘轮库): MyAppClass非常简单:Php 如何将$\u会话变量传递给websocket服务器?,php,apache,session,websocket,Php,Apache,Session,Websocket,我在网上搜索了很多,但没有找到有用的线索 我有一个websocket服务器和一个web服务器在本地机器上一起运行 当客户端使用浏览器API“new websocket(“ws://localhost”)”连接到websocket服务器时,我需要将$_会话数据传递到websocket服务器(请求使用反向代理发送到websocket,当接收到带有“Upgrade”头的请求时,反向代理会知道它) 关键是客户端成功地连接到ws-server,但我还需要使用HTTP web服务器设置的$u会话变量恢复它们
<?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();
}
}
正如其他StackOverflow答案所示(,),Apache和Ratchet进程之间无法直接共享$\u会话变量。但是,可以启动与Apache服务器的会话,然后在Ratchet代码中访问会话cookie
Apache服务器的index.html启动会话:
<?php
// Get the session ID.
$ses_id = session_id();
if (empty($ses_id)) {
session_start();
$ses_id = session_id();
}
?><!DOCTYPE html> ...
一旦两台服务器都知道用户的会话令牌,它们就可以使用该令牌通过MySQL数据库共享信息(我就是这么做的):
或者,您可以采用一种更奇特的进程间通信形式:
# 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);
这可能看起来有点粗糙,但这是我唯一能想出如何实现这一点的方法
假设您已经知道目录和sessionId,您可以直接使用session\u encode()
,session\u decode()
从会话文件中读取数据,如下所示。我的会话文件的前缀是sess\uu
,其他人可能不这样做,因此请记住这一点。请注意,从会话文件中提取变量后,这将保存并恢复任何现有的$\u会话
数据:
$contents = file_get_contents($sessionDir . 'sess_' . $sessionId);
$sessionData = $this->decodeSession($contents);
return $sessionData;
private function decodeSession($sessionString)
{
$currentSession = session_encode();
foreach ($_SESSION as $key => $value){
unset($_SESSION[$key]);
}
session_decode($sessionString);
$sessionVariables = $_SESSION;
foreach ($_SESSION as $key => $value){
unset($_SESSION[$key]);
}
session_decode($currentSession);
return $sessionVariables;
}
真的很聪明,但是“询问Apache进程关于使用cookie的用户”是什么意思呢?您如何实现这一点?我的意思是,如果我不使用DB进行会话,我需要让WebSocket服务器要求PHP使用会话id检索当前发送者的会话。我认为这是错误的方法,对吗<代码>消息上的公共函数(ConnectionInterface$from,$msg){$sessionId=$from->WebSocket->request->getCookies()['PHPSESSID'];session_id($sessionId);session_start();echo$_session['somekey'];}
这可靠吗?我认为你不能在WebSocket服务器内调用session_start();只有Apache服务器可以设置会话令牌,因为set cookie命令必须放在网页的标题中。一旦两台服务器都拥有会话令牌,您就可以决定如何使用会话令牌在进程间通信会话数据。由于Apache和Ratchet都是服务器,您可以通过自己清理来将数据从一个进程“服务”到另一个进程。很抱歉,我不明白,我明白我不能像我想象的那样使用sessession_start(),但要使Apache和Ratchet相互通信,我应该实现什么?从Ratchet调用并发送到Apache的web服务,以便根据会话标识符获取正确的数据,或者什么?感谢您的关注和关注!使用MySQL会话是否比使用简单的PHP会话更可靠、更具可扩展性?是的,这将起作用:“一个从Ratchet调用并发送到Apache的web服务,以便根据会话标识符获取适当的数据”。如果您没有DB,则可能不值得为Apache和Ratchet设置一个DB来共享数据。如果您已经有了数据库,那么存储和共享会话信息就相当容易了。
# 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);
$contents = file_get_contents($sessionDir . 'sess_' . $sessionId);
$sessionData = $this->decodeSession($contents);
return $sessionData;
private function decodeSession($sessionString)
{
$currentSession = session_encode();
foreach ($_SESSION as $key => $value){
unset($_SESSION[$key]);
}
session_decode($sessionString);
$sessionVariables = $_SESSION;
foreach ($_SESSION as $key => $value){
unset($_SESSION[$key]);
}
session_decode($currentSession);
return $sessionVariables;
}