Long Polling
wagtail_live.publishers.polling.LongPollingPublisher
Long polling Publisher. Class Based View.
This class handles delivering new updates to the client side (Long polling technique). It accepts 2 request methods (POST and GET) which correspond to the following steps:
-
The client side initiates (shake) the communication by sending a POST request. The publisher acknowledges by sending relevant data to the client side.
-
The client side asks new updates by sending a GET request.
Server side keeps the connection open until a new update is available. In that case, updates are directly sent to client side.
If the polling timeout duration is reached, it sends a response containing a
timeOutReached
parameter which indicates the client side that there aren't updates available.
get(self, request, channel_id, *args, **kwargs)
Sends updates when they are available as long as the polling timeout isn't reached.
See base class.
Source code in wagtail_live/publishers/polling.py
def get(self, request, channel_id, *args, **kwargs):
"""
Sends updates when they are available as long as the polling timeout isn't reached.
See base class.
"""
last_update_client = self.get_last_update_client_from_request(request=request)
polling_timeout = get_polling_timeout()
starting_time = time.time()
while time.time() - starting_time < polling_timeout:
live_page = get_object_or_404(self.model, channel_id=channel_id)
last_update_ts = live_page.last_update_timestamp
if last_update_ts > last_update_client:
tz = timezone.utc if settings.USE_TZ else None
updated_posts, current_posts = live_page.get_updates_since(
last_update_ts=datetime.fromtimestamp(last_update_client, tz=tz),
)
return JsonResponse(
{
"updates": updated_posts,
"currentPosts": current_posts,
"lastUpdateTimestamp": last_update_ts,
}
)
# Maybe propose a setting so the user can define this value
time.sleep(0.5)
return JsonResponse({"timeOutReached": "Timeout duration reached."})
post(self, request, channel_id, *args, **kwargs)
See base class.
Source code in wagtail_live/publishers/polling.py
def post(self, request, channel_id, *args, **kwargs):
"""See base class."""
live_page = get_object_or_404(self.model, channel_id=channel_id)
return JsonResponse(
{
"livePosts": [live_post.id for live_post in live_page.live_posts],
"lastUpdateTimestamp": live_page.last_update_timestamp,
}
)