获取Django中连接的用户列表

2 投票
2 回答
4257 浏览
提问于 2025-04-20 20:56

我想找个方法来记录用户在线和离线的状态。这样当我展示所有用户的列表时,就可以用一个图标或者某种标记来显示他们的状态。这在Django的默认认证系统中有内置功能吗?

我最初的想法是在我的用户资料中加一个叫做last_logout的字段,每次用户注销时更新这个字段,记录下日期和时间。

有了这个信息,再加上内置的last_login,我应该能写个函数来判断用户是否在线,对吧?

或者我应该直接加一个叫“online”的布尔字段,当用户登录和注销时改变这个字段的值?

2 个回答

3

你需要考虑“在线”对用户来说到底意味着什么。因为用户随时可以关闭浏览器窗口,而服务器并不知道这个动作,这样就会出现很多错误的“在线”用户。

你有两种基本的选择:

  • 记录用户最后一次活动的时间。每次用户加载一个页面时,你就更新这个时间。要获取所有在线用户的列表,你需要选择那些在X分钟内有活动的用户。这是一些网络论坛的做法。

  • 打开一个websocket、长轮询连接或者某种心跳机制与服务器保持连接。这是Facebook聊天的做法。你需要的不仅仅是django,因为保持连接需要另一种服务器端的资源。

5

仅仅使用Django来完成这个任务会比较困难。对于这种情况,异步框架会更合适。

比如说,Tornado就是一个不错的选择。

用户在离线时不会每次都明确地登出,他们只需关闭浏览器就可以了。仅靠Django的认证应用是无法知道这一点的,因为它并不是为这种情况设计的。

即使你检查会话是否过期,也无法获取所有在线用户,因为会话可以保持有效长达30天。

所以,要获取真正在线的用户,可以考虑以下解决方案:

  1. 每个用户可以通过JavaScript每隔10秒向你的服务器发送一些数据。你可以在服务器上接收这些数据,并将用户信息存入缓存,同时设置缓存的有效期为10秒。这样,当你想知道谁在线时,就可以查看缓存。不过,这并不是一个好的解决方案,因为会消耗很多服务器资源。
  2. 在服务器端使用异步框架(比如Tornado),你可以为特定请求设置单独的进程。同时在客户端使用WebSockets(SockJS是一个很好的库)。这个方案更复杂,但效果更好。

撰写回答