Archived

This forum has been archived. Please start a new discussion on GitHub.

Save object in PHP session

We developing a web app that uses Ice and PHP. In each PHP page we create Ice communicator using Ice_Initialize() with some init data, then get router through getDefaultRouter, then create session from router using login and password stored in PHP $_SESSION . Each time that done, the PermissionsVerifier asks database for login/password validity and then creates a servant object. So, each page visit and each async Ajax query does authenicate and create new object. Turning on logging for authentication process, we get a bunch of messages that says "User xxx logged in". We was trying to find a way to save proxy object between queries (using Ice_Find(), stringToProxy(), proxyToString() etc) to keep it alive and not need to save login/password in PHP session, but no success, we get null object from stringToProxy(). Is this saving possible in any way? Or maybe login info saving in PHP session method is a common way for writing authenticated Ice'd applications in PHP?

Comments

  • mes
    mes California
    Hi Dmitry,

    The lifetime of a Glacier2 session is limited to the lifetime of the connection between the client and the router. Furthermore, the session can only be used by this originating connection. Once the connection is closed for any reason, the session can no longer be used and becomes eligible for destruction.

    These semantics make it difficult to use a Glacier2 router from PHP. The Ice extension for PHP automatically destroys your communicator at the end of each PHP request, which means all connections established by that communicator are closed.

    Ice does provide a solution for this, we call it "registered communicators." Briefly, the PHP script notifies Ice that a communicator instance should not be destroyed at the end of the request. This allows a subsequent request to retrieve that instance and continue to use it.

    For this to work, PHP requests need to be serviced by the same Web server process. (A communicator instance is "alive" inside a persistent Web server process, so the only way two successive PHP requests can reuse the same communicator is if those requests are executed by the same process.) Depending on the Web server you are using, this may or may not be difficult to accomplish. For example, you could configure an Apache instance to have at most only one child process, but of course that might limit your application's responsiveness.

    If you haven't already seen it, Ice for PHP includes a Glacier2 example in the demo/Glacier2/hello directory.

    Regards,
    Mark
  • Hi Mark,
    Thanks for comprehensive answer. My web server is configured to use PHP in single process, so registered communicator is working. Ice_register($ICE, session_id(), session_cache_expire()) in one page allows me to get working communicator pointer when i use $ICE = Ice_find(session_id()) in another. But communicator is not only i need, another object i get from it is router:
    [PHP]$router = Glacier2_RouterPrxHelper::checkedCast($ICE->getDefaultRouter());
    //and finally
    $dbshell=Meteor_IDbShellPrxHelper::uncheckedCast($session=$router->createSession($user, $password));[/PHP]
    the last one is a subject to save between sessions, i can do it that way:
    [PHP]$_SESSION["obj_dbshell"] = $ICE->proxyToString($dbshell);
    // String here is like "92b32ff4-7d09-4a12-8e39-59163928999b -t:tcp -h 192.168.0.12 -p 10001"
    // IP address is an ICE server[/PHP]
    and in another page, restore:
    [PHP]$dbshell=Meteor_IDbShellPrxHelper::checkedCast($ICE->stringToProxy($_SESSION["obj_dbshell"]));[/PHP]
    When second page refreshed frequently, all works fine. The only trouble is, if i wait 15-20 seconds, then refresh it, call checkedCast throws Ice_ConnectionLostException. When i do, i have again to get router and call createSession() on it, thus complete login procedure each time page refreshed. Need some guru's help on it, where is this little timeout from, and how to increase it to appropriate value (session_expire() returns 180, so 180 minutes would be fine :rolleyes:)
  • mes
    mes California
    Hi,

    I'm glad to hear you got it working.

    Regarding the ConnectionLostException, there are two settings you should check. First, you must disable client-side active connection management by setting Ice.ACM.Client=0 in your PHP script. This feature automatically closes idle connections (after 60 seconds by default), and we generally recommend disabling it when using Glacier2.

    Second, review the setting for Glacier2.SessionTimeout in your Glacier2 configuration. Setting this property to a non-zero value enables automatic session destruction after a session has been idle for the given number of seconds.

    Hope that helps,
    Mark
  • Hi Mark,
    Seems it is working now. Ice.ACM.Client was 0 already, setting Glacier2.SessionTimeout to zero i've got no timeouts and lost connections. Thanks!