在App和聊天服务器之间共享会话(Symfony& Memcache)

时间:2016-09-01 15:28:00

标签: php symfony session memcached ratchet

尝试了解如何在我的应用和聊天服务器(Ratchet)之间共享会话数据。我想用Symfony& Memcache很容易,但我似乎无法让它工作。

我试图让import PyPlot a = vec( rand( 1:1000, 400, 300 )) b = vec( rand( 200:700, 400, 300 )) c = vec( rand( 300:1200, 400, 300 )) common_params = Dict( :bins => 20, :range => (-100, 1300), :normed => true ) PyPlot.subplots_adjust( hspace=.4 ) PyPlot.subplot( 311 ) PyPlot.title( "Default" ) PyPlot.plt[:hist]( a; common_params... ) PyPlot.plt[:hist]( b; common_params... ) PyPlot.plt[:hist]( c; common_params... ) PyPlot.subplot( 312 ) PyPlot.title( "Skinny shift - 3 at a time" ) PyPlot.plt[:hist]( (a, b, c); common_params... ) PyPlot.subplot( 313 ) common_params[:histtype] = "step" PyPlot.title( "With steps" ) PyPlot.plt[:hist]( a; common_params... ) PyPlot.plt[:hist]( b; common_params... ) PyPlot.plt[:hist]( c; common_params... ) PyPlot.savefig( "3hist.png" ) PyPlot.show() # PS, this is unnecessary in PyPlot. All commands show instantly 退出会话,当有人向聊天发送消息时,它会将user_id插入数据库(user_id)。

有人能指出我正确的方向吗?

流量:

    每页都包含
  1. Chat->onMessage
  2. 当用户登录网站时,它会执行config.php方法
  3. 我通过命令行($login->processLogin()
  4. 启动聊天服务器

    的config.php

    php server.php

    登录

    <?php
    use MyApp\Login;
    use MyApp\Session as MySession;
    
    # Define backslash or forward slash for *NIX and IIS systems.
    define('DS', DIRECTORY_SEPARATOR);
    # Attempt to determine the full-server path to the 'root' folder in order to reduce the possibility of path problems.
    define('BASE_PATH', realpath(dirname(__FILE__)).DS);
    
    # Define the complete path to the root of the domain we are at (ie. /home/user/domain.com) (does't end in a slash)
    define('ROOT_PATH', $_SERVER['DOCUMENT_ROOT']);
    # Define where cookies may be active. ('/' means the entire domain)
    define('COOKIE_PATH', '/');
    # Name sessions. (needs to be alphanumeric with no periods[.]- can't be solely digits; must contain at least one letter)
    define('SESSIONS_NAME', 'SiteUser');
    
    # Get the Session Class.
    require_once BASE_PATH.'modules'.DS.'Session'.DS.'Session.php';
    # Check if there is a session id set the the $sesh_id variable.
    $sesh_id=((isset($sesh_id)) ? $sesh_id : NULL);
    # Create a new session object, thus starting a new session.
    $mysession=MySession::getInstance(NULL, NULL, NULL, $sesh_id);
    

    会话

    <?php
    namespace MyApp;
    
    use Exception;
    
    # Make sure the script is not accessed directly.
    if(!defined('BASE_PATH'))
    {
        exit('No direct script access allowed');
    }
    
    # Get the User Class
    require_once BASE_PATH.'modules'.DS.'Login'.DS.'User.php';
    
    /**
     * Class Login
     *
     * The Login Class is used to login in and out users as well as checking various login privileges.
     */
    class Login extends User
    {
        /**
         * processLogin
         *
         * Checks if the Login has been submitted and processes it.
         *
         * @access    public
         */
        public function processLogin()
        {
            if($this->isLoggedIn()===TRUE)
            {
                header("location: main.php");
                die;
            }
    
            # Check if the form has been submitted.
            if($_SERVER['REQUEST_METHOD']=='POST')
            {
                try
                {
                    try
                    {
                        $this->setLoginSessions($this->getID(), TRUE);
                        header("location: main.php");
                    }
                    catch(Exception $e)
                    {
                        throw $e;
                    }
                }
                catch(Exception $e)
                {
                    throw $e;
                }
            }
        }
    
        /**
         * Checks if user is logged in or not. Returns TRUE if logged in, FALSE if not.
         *
         * @return bool
         */
        public function isLoggedIn()
        {
            global $mysession;
            $symfony_session=$mysession->symfony_session;
    
            //if(!isset($_SESSION['user_logged_in']))
            if(!$symfony_session->has('user_id'))
            {
                # Check if we have a cookie
                if(isset($_COOKIE['cookie_id']))
                {
                    try
                    {
                        $this->setID($_COOKIE['cookie_id']);
                    }
                    catch(Exception $e)
                    {
                        unset($_COOKIE['user_ip']);
                        unset($_COOKIE['athenticate']);
                        unset($_COOKIE['cookie_id']);
    
                        return FALSE;
                    }
                }
                else
                {
                    return FALSE;
                }
            }
            //elseif($_SESSION['user_logged_in']===TRUE)
            if($symfony_session->get('user_logged_in')===TRUE)
            {
                return TRUE;
            }
    
            return FALSE;
        }
    
        /**
         * Sets the login sessions.
         *
         * @param null $user_id
         * @param null $logged_in
         * @param bool $secure
         * @throws Exception
         */
        public function setLoginSessions($user_id=NULL, $logged_in=NULL, $secure=FALSE)
        {
            global $mysession;
            $symfony_session=$mysession->symfony_session;
    
            # Check if the user is logged in.
            if($this->isLoggedIn()===TRUE)
            {
                if($user_id===NULL)
                {
                    try
                    {
                        # Get the User's data.
                        $this->findUserData();
                        $user_id=$this->getID();
                        $logged_in=TRUE;
                    }
                    catch(Exception $e)
                    {
                        throw $e;
                    }
                }
            }
            $symfony_session->set('user_id', $user_id);
            $symfony_session->set('user_logged_in', $logged_in);
            /*
            # Set the User's login sessions.
            $_SESSION['user_id']=$user_id;
            $_SESSION['user_logged_in']=$logged_in;
            */
        }
    }
    

    server.php

    <?php
    namespace MyApp;
    
    use Memcache;
    use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
    use Symfony\Component\HttpFoundation\Session\Storage\Handler;
    use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
    use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcacheSessionHandler;
    
    /**
     * Class Session
     *
     * The Session class is used to access and manipulate Sessions and data stored in them.
     */
    class Session
    {
        private static $session;
        private $message=FALSE;
        private $sessname=FALSE;
        public $symfony_session;
    
        /**
         * Session constructor.
         *
         * Safely calls session_start().
         * Also enables sessions to span sub domains. It names the session (which is necessary for
         * session_set_cookie_params() to work). If calling this class before setting.php, $sessname (the session name) AND
         * $cookiepath (the path for cookies) MUST be defined.
         *
         * @param null $sessname
         * @param null $cookiepath
         * @param bool $secure
         * @param null $sesh_id
         */
        public function __construct($sessname=NULL, $cookiepath=NULL, $secure=FALSE, $sesh_id=NULL)
        {
            require_once BASE_PATH.'vendor'.DS.'autoload.php';
            $memcache=new Memcache;
            $memcache->connect(DOMAIN_NAME, 11211);
            $storage=new NativeSessionStorage(array(), new Handler\MemcacheSessionHandler($memcache));
            $symfony_session=new SymfonySession($storage);
    
            # Check if a session ID was passed.
            if($sesh_id!==NULL)
            {
                //session_id($sesh_id);
                $symfony_session->setId($sesh_id);
            }
            # Is a session already started?
            //if(!isset($_SESSION['s_set']))
            if(!$symfony_session->has('s_set'))
            {
    
                # If we haven't been given a session name, we will give it one.
                if(empty($cookiepath))
                {
                    # Set the default cookie path be the root of the site.
                    $cookiepath=DS;
                    # Check if the cookie path was defined in settings.php.
                    if(defined('COOKIE_PATH'))
                    {
                        # Check if the defined path is blank.
                        if(COOKIE_PATH!='')
                        {
                            # If the cookie path has been defined in settings.php, we'll use that path.
                            $cookiepath=COOKIE_PATH;
                        }
                    }
                }
                //session_set_cookie_params($life, $cookiepath, '.'.DOMAIN_NAME, $secure);
    
                /*
                 * Read the current save path for the session files and append our own directory to this path.
                 * Note: In order to make that platform independent, we need to check for the file-seperator first.
                 * Now we check if the directory already has been created, if not, create one.
                 * Then we set the new path for the session files.
                 */
                # Get the session save path.
                $save_path=session_save_path();
                # Find out if our custom_session folder exists. If not, let's make it.
                if(!is_dir(BASE_PATH.'../custom_sessions'.DS.'.'))
                {
                    mkdir(BASE_PATH.'../custom_sessions', 0755);
                }
                # Is our custom_sessions folder the session save path? If not, let's make it so.
                if($save_path!==BASE_PATH.'../custom_sessions')
                {
                    //session_save_path(BASE_PATH.'../custom_sessions');
    
                    # How do I set the save path in Symfony?
                }
    
                # If we haven't been given a session name, we will give it one.
                if(empty($sessname))
                {
                    # Set the default session name.
                    $sessname='PHPSESSID';
                    # Check if the session name was defined in settings.php.
                    if(defined('SESSIONS_NAME'))
                    {
                        # Check if the defined name is blank.
                        if(SESSIONS_NAME!='')
                        {
                            # If the session name has been defined in settings.php, we'll give the session that name.
                            $sessname=SESSIONS_NAME;
                        }
                    }
                }
                $storage->setOptions(array(
                    'cookie_domain'=>'.'.DOMAIN_NAME,
                    'cookie_lifetime'=>0,
                    'cookie_path'=>$cookiepath,
                    'cookie_secure'=>$secure,
                    'name'=>$sessname
                ));
                //$this->setSessname($sessname);
                # Name the session.
                //session_name($this->getSessname());
    
                # Session must be started before anything.
                //session_start();
                //$session->setName($this->getSessname());
                $symfony_session->start();
    
                # Set the s_set session so we can tell if session_start has been called already.
                //$_SESSION['s_set']=1;
                $symfony_session->set('s_set', 1);
            }
    
            $this->symfony_session=$symfony_session;
    
            print_r($symfony_session);exit;
        }
    
        /**
         * getSessname
         *
         * Returns the data member $sessname.
         *
         * @access    public
         */
        public function getSessname()
        {
            return $this->sessname;
        }
    
        /**
         * Sets the data member $sessname. If an empty value is passed, the data member will
         * be set with FALSE. Returns the set data member value.
         *
         * @param $sessname
         * @return bool
         */
        public function setSessname($sessname)
        {
            # Clean it up...
            $sessname=trim($sessname);
            # Check if the passed value is now empty.
            if(empty($sessname))
            {
                # Explicitly set the data member to false.
                $sessname=FALSE;
            }
            # Set the data member.
            $this->sessname=$sessname;
    
            # Return the data member after it has gone through the get method.
            return $this->getSessname();
        }
    
        /**
         * Gets the singleton instance of this class.
         *
         * @param null $sessname
         * @param null $cookiepath
         * @param bool $secure
         * @param null $sesh_id
         * @return Session
         */
        public static function getInstance($sessname=NULL, $cookiepath=NULL, $secure=FALSE, $sesh_id=NULL)
        {
            if(!self::$session)
            {
                self::$session=new Session($sessname, $cookiepath, $secure, $sesh_id);
            }
    
            return self::$session;
        }
    }
    

    聊天

    <?php
    use Ratchet\Server\IoServer;
    use Ratchet\Http\HttpServer;
    use Ratchet\WebSocket\WsServer;
    use Ratchet\Session\SessionProvider;
    use Symfony\Component\HttpFoundation\Session\Storage\Handler;
    use MyApp\Chat;
    
    $port="8080";
    
    # Change to this directory.
    chdir(dirname(__FILE__));
    
    # Need this for the database insert.
    if(!defined('DOMAIN_NAME'))
    {
        define('DOMAIN_NAME', 'example.dev');
    }
    
    require_once '../../includes/lonconfig.php';
    require_once '../../vendor/autoload.php';
    
    $memcache=new Memcache;
    $memcache->connect(DOMAIN_NAME, 11211);
    
    $session=new SessionProvider(
        new Chat,
        new Handler\MemcacheSessionHandler($memcache)
    );
    
    $server=IoServer::factory(
        new HttpServer(
            new WsServer($session)
        ),
        $port,
        DOMAIN_NAME
    );
    
    $server->run();
    

1 个答案:

答案 0 :(得分:1)

您实际上不应该在应用程序的所有部分共享该数据。

如果您打开Ratchet的教程,您将找到有关pushServers的部分。

这样您就可以推送到某个channel$user_id(在您的情况下)

这使您无法保存或传输这两部分中的数据,并且可以帮助您简化工作流程。

我个人在多个渠道中使用pushServer,它们分为:

  • 所有在线用户(sendBroadcast)
  • 组中的所有用户(sendGroup)
  • 所有关注标记的用户(sendTag)
  • 致其他用户(sendToUser)

我希望这已经让你知道如何解决你的问题,否则随便问。