{"id":2206,"date":"2018-11-08T06:56:21","date_gmt":"2018-11-08T06:56:21","guid":{"rendered":"https:\/\/www.migenius.com\/?p=2206"},"modified":"2018-11-08T06:56:21","modified_gmt":"2018-11-08T06:56:21","slug":"managing-user-sessions-with-uac-in-realityserver","status":"publish","type":"post","link":"https:\/\/www.migenius.com\/articles\/managing-user-sessions-with-uac-in-realityserver","title":{"rendered":"Managing User Sessions with UAC in RealityServer"},"content":{"rendered":"
In this article we’ll take a quick look at how to use the UAC system in RealityServer to effectively manage user sessions and clean up server memory when users go away. There won’t be a lot of pretty pictures (well there is one if you make it to the end) but for those of you getting your hands dirty with RealityServer in production, you’ll get some valuable pointers to help keep your server from filling up with unused data.<\/p>\n
<\/p>\n
No, it’s not that annoying dialog which pops up in Windows when you need administrator privileges (although that has the same acronym), it’s a system built into RealityServer which allows for a level of resource management such as controlling the number of users, their sessions and data associated with each user. In a real-world deployment where a users browser talks directly to RealityServer, having some measure of control over how loaded the server can become is very important.<\/p>\n
You can learn more about UAC in our online documentation<\/a> or in your RealityServer Document Center by under Server APIs<\/em> \u2192 RealityServer Web Services API Programming Manual<\/em> \u2192 User Access Control System<\/em>. In this article we’ll just cover the most important and common ways to use this system.<\/p>\n Setting up UAC is dead simple. Everything is configured in your realityserver.conf<\/em> file and you’ll find commented out entries in the default file to help (UAC is disabled by default). For configuration you can find full documentation<\/a> online or in the Document Center of your RealityServer under Getting Started<\/em> \u2192 RealityServer Configuration<\/em> \u2192 UAC Directives<\/em>. Here’s a run down of the three most important options, however we definitely recommend checking out the documentation for more.<\/p>\n The uac_auto_session<\/em> option is on by default and usually there is no reason to turn it off. You can remind yourself it is enabled by explicitly having this in your realityserver.conf<\/em>.<\/p>\n With this option on (or not specified), if UAC is enabled (by specifying a user limit, see the next section) then each connection to a UAC protected resource will automatically create a session for the user and setup a cookie in the client side to track this. If you disable automatic session creation you’ll need to manually manage sessions which we don’t recommend unless you have a specific reason for it. With automatic sessions on, when a new user makes a request you will see messages like this in your logs.<\/p>\n This indicates that 2 out of a possible 5 sessions are in use now and that a new session has just been created. As you can see UAC log message have their own prefix making them easy to search for when tracking issues. So, leave this option enabled, make your life easy.<\/p>\n The uac_user_limit<\/em> directive controls how many users are allowed to access RealityServer resources protected by UAC simultaneously. Let’s say you have a server which you know can handle up to 5 users at once and rather than provide a substandard experience to the 6th user you’d prefer to let them know you’re so popular that the server is busy right now and you are buying more to meet demand. In your realityserver.conf<\/em> you simply add the following directive.<\/p>\n When the user limit is exceeded you will see a message like this in the logs.<\/p>\n On the client side your request will get a HTTP 503<\/a> response with the reason At Capacity<\/em>. This is useful since you can explicitly look for this in your client side code if it was an XHR request and respond accordingly in your application instead of having a generic error (assuming the page requesting the resource can be loaded, more on that later).<\/p>\n If you have a reverse proxy setup such as with haproxy you can also do clever things with the status codes to redirect to other resources you may want the user to see.<\/p>\n Now these sessions would all be pretty useless if they were just created and never destroyed so we need a way to remove them. Unfortunately, browser do not tell you when the user just closes a tab and there is no opportunity to execute clean up code, this leaves only one choice, the dreaded session timeout. It’s a necessary evil but you can easily configure it in your realityserver.conf<\/em> like this.<\/p>\n This is specified in seconds and what this means is if a session has not been used to fulfil a request in the specified time (in this example 120 seconds) then the session will be expired and it’s slot in the user limit made available for someone else. If no user requests were made and the timeout is reached you will see something like this in the logs.<\/p>\n By default freeing up the user count is the only effect of this, but as we will see later this is one other much more powerful piece of functionality this can be combined with.<\/p>\n Scopes are an important part of managing users, data and memory usage in RealityServer. Basically scopes cordon off parts of the database so that the elements within them can be isolated from the rest of the database. In a multi-user system like RealityServer this is critical since most of the time you don’t want one user modifying the others camera for example (although there are some uses cases where you might want that).<\/p>\n If you don’t do anything with scopes then everything in the RealityServer database ends up in the global scope and is visible to everyone. As such most applications will use scopes to isolate users from each other and chose which data should be shared and which kept private. Now, I started writing a “brief” introduction to scopes and it was already longer than this article so we’ll save a full explanation for another post. For now, the important take away is that you want to gather all of the data specific to a given user in RealityServer under a scope (or set of scopes) to keep it together.<\/p>\n Why is this all so important? Well UAC has a magic feature I haven’t talked about yet and that is the ability to associate scopes with sessions. This is really cool since once you do this, when a session expires after its timeout is reached, it will magically remove all of the scopes associated with it and all of the data within them along with it. This is what allows you to stop your server filling up with the memory of thousands of long dead sessions.<\/p>\n To associate a scope with a session you need to explicitly call a special UAC system URL. Let’s say you have a scope called application_scope<\/em> that you want to associate with your session. You just need to request the following URL from RealityServer.<\/p>\n This is one of the URLs used to manually control UAC (see below), they are all at \/uac\/<\/em> by default. (though you can reconfigure that if needed). This one takes the scope name in the final part of the path and it will associate the scope with the current session.<\/p>\n Naturally you need to make sure your environment already has a session when making this request so you need to have called at least one UAC protected resource before doing it (you will likely have done that when issuing the commands to create the scopes in the first place).<\/p>\n You need to associate all scopes you use in your application that you want to be released when the users session expires, so if your application has child scopes you’ll need to associate those as well. If the association succeeds the request will return a normal HTTP 200 with the response body containing the text OK<\/em>. You will then see a message like this in the logs.<\/p>\n Now when a user session expires your associated scopes are automagically removed and you will see something like this in the logs.<\/p>\n Neat! If you check your RealityServer Admin console (on port 8081 by default) in your browser you can check that the scope and database elements in it were removed. Note that everything in the RealityServer database is reference counted, so if, for example you have something still using the element elsewhere it won’t be removed until that reference goes away as well.<\/p>\n This is probably the single biggest reason to use UAC and carefully manage scopes. Most of our customers wish to run their RealityServer instances for very long periods of time without restarting, that requires careful management of data and these tools make it possible.<\/p>\n While all of the HTTP requests needed to setup Web Sockets are subject to the normal UAC system, once established, the Web Socket communication is completely independent and the UAC system has no knowledge of what it is doing. As such in order to ensure your sessions do not timeout if you are performing all of your operations over Web Sockets (for example if you are just rendering and navigating the camera), you will need to send regular “keep alive” pings over the normal HTTP connection. This can really be any request that goes over regular HTTP to a UAC protected URL, you just need to ensure it is sent at an interval less than your session timeout.<\/p>\n By default everything, every single HTTP request made to RealityServer will be subjected to UAC unless you explicitly exempt URLs. This means even requesting the favicon.ico file will create a session for example. This is likely not what you want and you are probably more interested in protecting access to RealityServer commands.<\/p>\n You can exempt specific URLs from having UAC applied to them by adding the apply_uac off<\/em> directive to the URLs section in your realityserver.conf<\/em>. Commonly you’d want to exclude your applications webpages and other resources which don’t incur much computational cost to serve, here’s an example.<\/p>\n These are the URL paths as seen by the requesting client, not the file system. So in a default RealityServer installation for example \/applications\/<\/em> refers to the content in content_root\/applications<\/em> and so on. One important reason to exclude your applications themselves is so you can serve the webpage which contains the logic that creates requests that do make sessions. This allows you to check if session creation worked and if not display something in the UI. Otherwise you’ll just be left with the generic HTTP 503 page. Of course you may be hosting your client side pages somewhere other than RealityServer in which case it wouldn’t be an issue.<\/p>\n You can find full documentation<\/a> for URL directives online or in the Document Center of your RealityServer under Getting Started<\/em> \u2192 RealityServer Configuration<\/em> \u2192 URL Directives<\/em>.<\/p>\n The most common way to use UAC is with the uac_auto_session<\/em> option turned on (the default) so you never need to worry about explicitly making user sessions. However if you want more control you can turn this off. When you do, you’ll need to use the manual URL requests to control UAC. We saw a small example of this above for associating sessions. There are two more session management URLs you can call. Note the trailing slash is required.<\/p>\n \/uac\/create\/<\/a> \u2014 will create a new session and set the appropriate cookie in the response. If the session limit is exceeded a HTTP 503 is returned instead.<\/p>\n \/uac\/destroy\/<\/a> \u2014 will immediately destroy the session (and associated scopes) specified by the cookie in the request. It will return a HTTP 400 if no session cookie is found.<\/p>\n These requests are all called as HTTP GET. You can also combine the manual control with the automated control. For example if you have an application which does have explicit exit buttons or controls to stop RealityServer you can use these URLs to take those actions immediately and not wait for timeouts.<\/p>\n Don’t worry, I’m not going to subject you to it in this article though. However there are some other really nice things that can be done with UAC. For example, RealityServer ships with an example C++ plugin which allows it to automatically update server weights in an HAProxy<\/a> based load balancer, great when you have multiple servers and you want to find out which is the least busy to send requests to. This plugin uses the UAC event handler system which basically lets you hook any functionality you want up to UAC events such as session creation and destruction.<\/p>\n That was pretty dry stuff so here are three cute octopuses waving hello to you, because, well why not and you made it this far and deserve something nice. Of course, we think UAC is pretty interesting and hope you get to make good use of it.<\/p>\n\n Of course, they are rendered with RealityServer in Iray Photoreal mode with lots of healthy sub-surface scattering. We’d love it if you’d say hello and reach out to us<\/a> to talk more about RealityServer.<\/p>\n The Cute Octopus Says Hello<\/a> model is by MakerBot and is licensed under the Creative Commons – Attribution license<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":" In this article we’ll take a quick look at how to use the UAC system in RealityServer to effectively manage user sessions and clean up server memory when users go away. There won’t be a lot of pretty pictures (well there is one if you make it to the end) but for those of you […]<\/p>\n","protected":false},"author":2,"featured_media":2205,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"spay_email":"","jetpack_publicize_message":"Managing User Sessions with UAC in RealityServer","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[15,30],"tags":[33,14,27,32],"jetpack_featured_media_url":"https:\/\/www.migenius.com\/migenius\/wp-content\/uploads\/2018\/11\/uac_feature.jpg","_links":{"self":[{"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/posts\/2206"}],"collection":[{"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/comments?post=2206"}],"version-history":[{"count":9,"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/posts\/2206\/revisions"}],"predecessor-version":[{"id":2215,"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/posts\/2206\/revisions\/2215"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/media\/2205"}],"wp:attachment":[{"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/media?parent=2206"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/categories?post=2206"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.migenius.com\/wp-json\/wp\/v2\/tags?post=2206"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}Features and Configuration<\/h3>\n
Automatic Session Creation<\/h4>\n
\nuac_auto_session on\n<\/pre>\n
\n18\/11\/08 14:09:01 1.19 UAC main info : Registering new session 1tYesuA41TNh3CiTLhUqz*tp9fNxZt, 2\/5 used.\n<\/pre>\n
User Limit<\/h4>\n
\nuac_user_limit 5\n<\/pre>\n
\n18\/11\/08 14:22:48 1.16 UAC main info : Session rejected, already have 5 sessions.\n<\/pre>\n
Session Timeout<\/h4>\n
\nuac_session_timeout 120\n<\/pre>\n
\n18\/11\/08 14:23:17 1.13 UAC main info : Expiring session 1tYesuA41TNh3CiTLhUqz*tp9fNxZt.\n18\/11\/08 14:23:17 1.13 UAC main info : 3\/5 sessions used.\n<\/pre>\n
Sessions and Scopes<\/h3>\n
What is a Scope<\/h4>\n
Associating a Scope with a Session<\/h4>\n
\nhttp:\/\/host:port\/uac\/associate_scope\/application_scope\n<\/pre>\n
\n18\/11\/08 12:24:18 1.15 UAC main info : Associated scope application_scope with session 1tYesuA41TNh3CiTLhUqz*tp9fNxZt.\n<\/pre>\n
\n18\/11\/08 12:24:56 1.13 UAC main info : Expiring session 1tYesuA41TNh3CiTLhUqz*tp9fNxZt.\n18\/11\/08 12:24:56 1.13 UAC main info : Removing associated scope application_scope.\n18\/11\/08 12:24:56 1.13 UAC main info : 1\/5 sessions used.\n<\/pre>\n
Special Considerations for Web Sockets<\/h3>\n
What Does UAC Apply To?<\/h3>\n
\n<url \/applications\/>\napply_uac off\n<\/url>\n\n<url \/assets\/>\napply_uac off\n<\/url>\n\n<url \/favicon.ico>\napply_uac off\n<\/url>\n\n<url \/client_libraries\/>\napply_uac off\n<\/url>\n<\/pre>\n
Manually Controlling UAC<\/h3>\n
Wait There’s More!<\/h3>\n
Say Hello<\/h3>\n