问题描述
我正在考虑使用 django-notifications 和Web Sockets发送真实的到iOS/Android和Web应用的时间通知.所以我可能会使用 Django Channels .
I'm considering to use django-notifications and Web Sockets to send real-time notifications to iOS/Android and Web apps. So I'll probably use Django Channels.
我可以使用 Django频道实时跟踪用户的在线状态吗?如果是,那我如何在不不断轮询服务器的情况下实现这一目标?
Can I use Django Channels to track online status of an user real-time? If yes then how I can achieve this without polling constantly the server?
由于找不到合适的解决方案,我正在寻找最佳实践.
I'm looking for a best practice since I wasn't able to find any proper solution.
更新:
到目前为止,我尝试了以下方法:我使用Django Channels实现了一个WebSocket使用者,该使用者在连接时会将用户状态设置为'online'
,而当套接字断开连接时,用户状态将设置为'offline'
.最初,我想包含'away'
状态,但是我的方法无法提供此类信息.另外,当用户从多个设备上使用应用程序时,我的实现将无法正常工作,因为连接可以在一个设备上关闭,但在另一个设备上仍然可以打开;即使用户有另一个打开的连接,状态也将设置为'offline'
.
What I have tried so far is the following approach:Using Django Channels, I implemented a WebSocket consumer that on connect will set the user status to 'online'
, while when the socket get disconnected the user status will be set to 'offline'
.Originally I wanted to included the 'away'
status, but my approach cannot provide that kind of information.Also, my implementation won't work properly when the user uses the application from multiple device, because a connection can be closed on a device, but still open on another one; the status would be set to 'offline'
even if the user has another open connection.
class MyConsumer(AsyncConsumer):
async def websocket_connect(self, event):
# Called when a new websocket connection is established
print("connected", event)
user = self.scope['user']
self.update_user_status(user, 'online')
async def websocket_receive(self, event):
# Called when a message is received from the websocket
# Method NOT used
print("received", event)
async def websocket_disconnect(self, event):
# Called when a websocket is disconnected
print("disconnected", event)
user = self.scope['user']
self.update_user_status(user, 'offline')
@database_sync_to_async
def update_user_status(self, user, status):
"""
Updates the user `status.
`status` can be one of the following status: 'online', 'offline' or 'away'
"""
return UserProfile.objects.filter(pk=user.pk).update(status=status)
注意:
我当前的工作解决方案是将Django REST Framework与API端点一起使用,以允许客户端应用发送具有当前状态的HTTP POST请求.例如,web应用程序轨道鼠标事件和不断POST每X秒的状态中,当没有更多的鼠标事件POST的状态,当拉片/窗口即将被关闭时,该应用发送一个状态为offline
的POST请求.这是一个可行的解决方案,具体取决于浏览器,当我发送offline
状态时遇到问题,但是它可以正常工作.
My current working solution is using the Django REST Framework with an API endpoint to let client apps send HTTP POST request with current status.For example, the web app tracks mouse events and constantly POST the online
status every X seconds, when there are no more mouse events POST the away
status, when the tab/window is about to be closed, the app sends a POST request with status offline
.THIS IS a working solution, depending on the browser I have issues when sending the offline
status, but it works.
我正在寻找的是一种更好的解决方案,不需要不断轮询服务器.
What I'm looking for is a better solution that doesn't need to constantly polling the server.
推荐答案
使用WebSockets绝对是更好的方法.
Using WebSockets is definitely the better approach.
您可以对连接数进行计数,而不必具有二进制的在线"/离线"状态:当连接新的WebSocket时,将在线"计数器加1,而当WebSocket断开连接时,将其减小.这样,当它为0
时,用户在所有设备上都处于脱机状态.
Instead of having a binary "online"/"offline" status, you could count connections: When a new WebSocket connects, increase the "online" counter by one, when a WebSocket disconnects, decrease it. So that, when it is 0
, then the user is offline on all devices.
类似这样的东西
@database_sync_to_async
def update_user_incr(self, user):
UserProfile.objects.filter(pk=user.pk).update(online=F('online') + 1)
@database_sync_to_async
def update_user_decr(self, user):
UserProfile.objects.filter(pk=user.pk).update(online=F('online') - 1)
这篇关于Django-如何实时跟踪用户在线/离线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!