1

Kind of curious as I'm aiming for a stateless setup, how some people go about coding/setting up their session handling when many devices accessing a single account occurs.

I work with Node.JS currently but the pseudo is appreciated,

This is how my sessions look currently, ID is a unique value. (Redis stored JSON by KEY)

{"cookie": {
    "originalMaxAge": null,
    "expires": null,
    "secure": true,
    "httpOnly": true,
    "domain": "",
    "path": "/",
    "sameSite": "strict"
},
"SameSite": "7e5b3108-2939-4b4b-afdc-39ed5dbd00d0",
"loggedin": 1,
"validated": 1,
"username": "Tester12345",
"displayself": 1,
"avatar": "{ \"folder\": \"ad566c0b-aeac-4db8-9f54-36529c99ef15/\", \"filetype\": \".png\" }",
"admin": 0,
"backgroundcolor": "#ffffff",
"namebackgroundcolor": "#000000",
"messagetextcolor": "#5d1414"}

I have no issues with this setup until I have a user logged in twice different devices and one decides to adjust their colors or avatar; one session is up to date and the other is completely lost.

I do my best when possibly to call out to database to ensure the information is up to date when it's most important but curious for this small slip up what I should be doing? I'd hate to call for database each request to get this information but think most do this any-how?

I could set up in my mind a hundred different ways to go about this but was hoping maybe someone who has dealt with this has some excellent ideas about this. I'd like to just be efficient and not make my databases work as hard if they don't need to, but I know session handling makes the call each request so trying to determine a final thought.


Open to all ideas, and my example above is a JSON insert into Redis; I'm open to changing to MySQL or another store.

BGPHiJACK
  • 1,277
  • 1
  • 8
  • 16
  • Are you just trying to synchronize server-side session objects such as express-session objects? Or are you trying to synchronous active client state such that if deviceA logged in as clientA changes their background color to green, then deviceB that is also logged in as clientA should immediately update it's device background to the new color? – jfriend00 Jan 08 '22 at 06:09
  • The later scenario, if DeviceA changes color on AccountA; DeviceB logged into AccountA should know as well. Wondering what some people do in these scenarios? – BGPHiJACK Jan 08 '22 at 13:32

1 Answers1

0

One way to notify devices and keep them up-to-date about changes made elsewhere is with a webSocket or socket.io connection from device to the server. When the device logs in as a particular user and then makes a corresponding webSocket or socket.io connection to the server, the server keeps track of what user that connection belongs to. The connection stays connected for the duration of the user's presence.

Then, if a client changes something (let's use a background color as an example), and tells the server to update its state to that new color, the server can look in its list of connections to see if there are any other connections for this same account. If so, the server sends that other connection a message indicating what change has been made. That client will then receive that notification and can update their view immediately. This whole thing can happen in milliseconds without any polling by the client.

If you aren't familiar with socket.io, it is a layer on top of webSocket that offers some additional features.

In socket.io, you can add each device that connects on behalf of a specific account to a socket.io room that has a unique name derived from the account (often an email address or username). Upon login:

// join this newly connected socket to a room with the name
// of the account it belongs to
socket.join(accountName);

Then, you can easily broadcast to all devices connected to that room with one simple socket.io API call:

// send a message to all currently connected devices using this account
io.emit(accountName, msg);

When socket.io connections are disconnected, they are automatically removed from any rooms that they have been placed in.

A room is a lightweight collection of currently connected sockets so it works quite well for a use like this.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Very well versed with Web Sockets; I run a server per room I host and inside the room no issues keeping a good sync, I even have my HTTPS servers signaling to these servers events so sync is no issue there if room owner wants to update stuff/make changes. – BGPHiJACK Jan 08 '22 at 19:10
  • Now for the entirety of the site, running a web socket for all users will prove challenging and won't scale properly at all! It would not make sense to have hundreds kept alive just to pend data that may or may not ever change. Your answer though is a good one to read through, I apply some of these concepts already! :) – BGPHiJACK Jan 08 '22 at 19:12
  • I'm mostly wanting to keep HTTPS sessions synced across devices without the help of expensive protocol usage. I guess a good example is with FaceBook, my avatar shows on every page, is face-book honestly going to call database every-time for this? It doesn't use websockets to share this data across accounts. The link is not fixed either. – BGPHiJACK Jan 08 '22 at 19:18
  • @BGPHiJACK - An avatar that rarely changes is going to be accessed from storage initially and then cached in memory for subsequent pages. In fact, if it's an image on the page, the browser itself is going to cache it. That cache may be outside the database or it may be part of the database such that you ask the database for it and it immediately responds from its own cache in memory. – jfriend00 Jan 08 '22 at 21:03
  • @BGPHiJACK - For simple stuff (I though your question was about much more important dynamic state), just store your data in an efficient database, take maximum advantage of browser caching and query the database when you need the data. If, as you scale, you run into performance issues with the database, then you profile, find out what resources would generate the most benefit by making them more efficient to access and then either build a purpose-built memory cache for those or find some more efficient way to cache/access them. – jfriend00 Jan 08 '22 at 21:10
  • @BGPHiJACK - This stuff is not worth overdesigning at the beginning of your project because you honestly don't know where your bottlenecks will be and its best to not engineer things that are not yet a problem. Then, you can spend the maximum amount of engineering on the things that matter the most once you have real performance data at scale. – jfriend00 Jan 08 '22 at 21:11
  • I agree, this is final touch stuff. I am well aware of my limits through some cannon attacks/etc. I am designing to be most efficient for my grow-up. :) So if I can sort a cool way do handle sessions I'll write my code to follow suite. – BGPHiJACK Jan 09 '22 at 00:59