You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.7 KiB
50 lines
1.7 KiB
from channels.layers import get_channel_layer
|
|
from asgiref.sync import async_to_sync
|
|
from threading import Timer
|
|
|
|
class WebSocketSender:
|
|
"""
|
|
Manages WebSocket notifications for users with individual buffering timers.
|
|
"""
|
|
def __init__(self):
|
|
self._user_timers = {} # Dictionary to store user-specific timers
|
|
self._buffer_timeout = 0.1 # Debounce timeout in seconds
|
|
|
|
def send_user_message(self, user_id, device_id):
|
|
"""
|
|
Schedules a notification for a specific user with debouncing.
|
|
"""
|
|
# print(f'>>> send message: {device_id}')
|
|
# Cancel existing timer for this user if any
|
|
if user_id in self._user_timers and self._user_timers[user_id]:
|
|
self._user_timers[user_id].cancel()
|
|
|
|
# Create new timer for this user
|
|
self._user_timers[user_id] = Timer(
|
|
self._buffer_timeout,
|
|
self._send_message,
|
|
args=[user_id, device_id]
|
|
)
|
|
self._user_timers[user_id].start()
|
|
|
|
def _send_message(self, user_id, device_id):
|
|
"""
|
|
Sends the WebSocket message for a specific user.
|
|
"""
|
|
channel_layer = get_channel_layer()
|
|
group_name = f"sync_{user_id}"
|
|
|
|
print(f">>> send to group {group_name}, device_id={device_id}")
|
|
# print(f'channel_layer = {channel_layer}')
|
|
|
|
device_id = device_id if device_id else "std_msg_lol" # a not empty message is required!
|
|
|
|
async_to_sync(channel_layer.group_send)(
|
|
group_name,
|
|
{"type": "sync.update", "message": device_id}
|
|
)
|
|
# Cleanup timer reference
|
|
self._user_timers[user_id] = None
|
|
|
|
# Create a singleton instance
|
|
websocket_sender = WebSocketSender()
|
|
|