Browse Source

Initial support for long-polling.

feature/long-poll-status
Daniel Perelman 1 year ago
parent
commit
93e521aca0
6 changed files with 72 additions and 8 deletions
  1. +16
    -0
      fear_tracker/routing.py
  2. +7
    -2
      fear_tracker/templates/game.html
  3. +1
    -3
      fear_tracker/urls.py
  4. +39
    -0
      fear_tracker/views.py
  5. +2
    -3
      fear_tracker_site/routing.py
  6. +7
    -0
      fear_tracker_site/settings.py

+ 16
- 0
fear_tracker/routing.py View File

@@ -0,0 +1,16 @@
from channels.http import AsgiHandler
from channels.routing import ProtocolTypeRouter, URLRouter

from django.conf.urls import url

from . import views

application = ProtocolTypeRouter({
"http": URLRouter([
url(r'^(?P<access_code>[a-zA-Z]{6})/', URLRouter([
url(r"status/(?P<hashcode>[a-z0-9]{64})/",
views.StatusLongPollConsumer, name='status'),
])),
url(r"", AsgiHandler),
]),
})

+ 7
- 2
fear_tracker/templates/game.html View File

@@ -360,7 +360,7 @@
el.addEventListener("change", formElementChanged);
}

setInterval(function() {
function checkStatus() {
if(activeRequests.size != 0) return;
fetch(new Request("{% url 'status' access_code=access_code %}"
+ (statusObj.hash != ""
@@ -381,8 +381,13 @@
} else {
statusObj = data;
}
})
.catch(() => {})
.then(() => {
checkStatus();
});
}, 5000);
}
checkStatus();
});
</script>
{% endif %}


+ 1
- 3
fear_tracker/urls.py View File

@@ -27,7 +27,5 @@ urlpatterns = [
path('update/', views.update_game, name='update_game'),
path('qr/', views.qr_code, name='qr_code'),
path('status/', views.status, name='status'),
url('^status/(?P<hashcode>[a-z0-9]{64})/',
views.status, name='status'),
])),
])),
]

+ 39
- 0
fear_tracker/views.py View File

@@ -5,6 +5,11 @@ import hashlib
import json
import qrcode

from asgiref.sync import async_to_sync

from channels.generic.http import AsyncHttpConsumer
from channels.layers import get_channel_layer

from django.db import transaction
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
@@ -278,6 +283,10 @@ def handle_game_request(request, game, update):
for player in players.values():
player.ready = True

async_to_sync(get_channel_layer().group_send)(
"%s_status" % game.access_code,
{"type": "fear_tracker.invalidate_status"})

if update:
if errors:
res = {
@@ -325,3 +334,33 @@ def status(request, game, hashcode=None):
else:
status_string = json.dumps(status_obj)
return HttpResponse(status_string)


class StatusLongPollConsumer(AsyncHttpConsumer):
async def handle(self, body):
self.access_code = self.scope["url_route"]["kwargs"]["access_code"]
self.hashcode = self.scope["url_route"]["kwargs"]["hashcode"]

await self.channel_layer.group_add("%s_status" % self.access_code,
self.channel_name)

async def http_request(self, message):
"""
Async entrypoint - concatenates body fragments and hands off control
to ``self.handle`` when the body has been completely received.
"""
if "body" in message:
self.body.append(message["body"])
if not message.get("more_body"):
await self.handle(b"".join(self.body))

async def disconnect(self):
await self.channel_layer.group_discard("%s_status" % self.access_code,
self.channel_name)

async def fear_tracker_invalidate_status(self, event):
no_hash_status = reverse('status',
kwargs={'access_code': self.access_code})
await self.send_response(302, b'', headers=[
(b"Location", no_hash_status.encode('utf-8'))
])

+ 2
- 3
fear_tracker_site/routing.py View File

@@ -1,4 +1,3 @@
from channels.routing import ProtocolTypeRouter
import fear_tracker.routing

# No async routing currently; just default sync http.
application = ProtocolTypeRouter({})
application = fear_tracker.routing.application

+ 7
- 0
fear_tracker_site/settings.py View File

@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition

INSTALLED_APPS = [
'channels',
'fear_tracker',
'django.contrib.admin',
'django.contrib.auth',
@@ -82,6 +83,12 @@ DATABASES = {
}
}

CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}


# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators


Loading…
Cancel
Save