【问题标题】:Keeping sync between two devices accessing the same account (different/same session)在访问同一帐户的两台设备之间保持同步(不同/相同的会话)
【发布时间】:2022-01-09 01:28:38
【问题描述】:

有点好奇,因为我的目标是无状态设置,当出现许多设备访问单个帐户时,有些人如何编写/设置会话处理。

我目前使用的是 Node.JS,但很感谢伪,

这是我的会话当前的样子,ID 是一个唯一值。 (Redis通过KEY存储JSON)

{"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"}

在我有一个用户登录两次不同的设备并决定调整他们的颜色或头像之前,我对此设置没有任何问题;一个会话是最新的,另一个完全丢失。

我尽我所能调用数据库以确保信息在最重要的时候是最新的,但对这个小错误我应该做什么感到好奇?我不想每次请求都调用数据库来获取这些信息,但我认为大多数人无论如何都会这样做?

我可以在脑海中设置一百种不同的方法来解决这个问题,但希望也许处理过这个问题的人对此有一些很好的想法。我只想提高效率,而不是让我的数据库在不需要时努力工作,但我知道会话处理会调用每个请求,因此试图确定最终想法。


对所有想法开放,我上面的例子是一个 JSON 插入 Redis;我愿意改用 MySQL 或其他商店。

【问题讨论】:

  • 您是否只是想同步服务器端会话对象,例如快速会话对象?或者您是否尝试同步活动客户端状态,以便如果作为 clientA 登录的 deviceA 将其背景颜色更改为绿色,那么也以 clientA 身份登录的 deviceB 应立即将其设备背景更新为新颜色?
  • 后面的场景,如果DeviceA在AccountA上改变颜色;登录到 AccountA 的 DeviceB 也应该知道。想知道有些人在这些情况下会做什么?

标签: mysql node.js session redis


【解决方案1】:

一种通知设备并使它们及时了解其他地方所做更改的方法是使用从设备到服务器的 webSocket 或 socket.io 连接。当设备以特定用户身份登录并与服务器建立相应的 webSocket 或 socket.io 连接时,服务器会跟踪该连接属于哪个用户。在用户存在期间,连接保持连接状态。

然后,如果客户端更改了某些内容(让我们以背景颜色为例),并告诉服务器将其状态更新为新颜色,服务器可以查看其连接列表以查看是否有其他连接同一帐户的连接。如果是这样,则服务器向该其他连接发送一条消息,指示已进行了哪些更改。然后该客户端将收到该通知并可以立即更新其视图。这整个事情可以在几毫秒内发生,而无需客户端进行任何轮询。

如果你不熟悉 socket.io,它是 webSocket 之上的一层,提供了一些additional features

在 socket.io 中,您可以将代表特定帐户连接的每个设备添加到 socket.io 房间,该房间具有从该帐户派生的唯一名称(通常是电子邮件地址或用户名)。登录后:

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

然后,您可以通过一个简单的 socket.io API 调用轻松地向连接到该房间的所有设备广播:

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

当 socket.io 连接断开时,它们会自动从它们所在的任何房间中删除。

房间是当前连接的套接字的轻量级集合,因此非常适合这样的用途。

【讨论】:

  • 非常精通Web Sockets;我在每个我托管的房间和房间内运行一个服务器,保持良好的同步没有问题,我什至让我的 HTTPS 服务器向这些服务器事件发出信号,因此如果房间所有者想要更新内容/进行更改,同步也没有问题。
  • 现在对于整个网站,为所有用户运行一个 Web 套接字将被证明具有挑战性,而且根本无法正常扩展!让数百个保持活动状态只是为了挂起可能会或可能不会改变的数据是没有意义的。您的答案虽然是一个很好的阅读答案,但我已经应用了其中一些概念! :)
  • 我主要希望在不使用昂贵协议的帮助下保持 HTTPS 会话跨设备同步。我想一个很好的例子是FaceBook,我的头像显示在每一页上,Facebook真的会为此每次调用数据库吗?它不使用 websockets 跨帐户共享此数据。链接也不固定。
  • @BGPHiJACK - 一个很少更改的头像最初将从存储中访问,然后缓存在内存中以供后续页面使用。事实上,如果它是页面上的图像,浏览器本身就会缓存它。该缓存可能在数据库之外,也可能是数据库的一部分,因此您向数据库请求它,它会立即从内存中自己的缓存中响应。
  • @BGPHiJACK - 对于简单的东西(我虽然你的问题是关于更重要的动态状态),只需将您的数据存储在一个高效的数据库中,最大限度地利用浏览器缓存并在需要时查询数据库数据。如果在扩展时遇到数据库的性能问题,那么您可以进行分析,找出哪些资源可以通过提高访问效率来产生最大的收益,然后为这些资源构建专门构建的内存缓存,或者找到一些更有效的缓存/访问方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 2014-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
相关资源
最近更新 更多