Compare commits
2 Commits
2ecf8b51de
...
464dfc1246
Author | SHA1 | Date | |
---|---|---|---|
464dfc1246 | |||
acf18382ad |
|
@ -1,17 +0,0 @@
|
|||
from channels.http import AsgiHandler
|
||||
from channels.routing import ProtocolTypeRouter, URLRouter
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
# No async routing currently; just default sync http.
|
||||
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),
|
||||
]),
|
||||
})
|
|
@ -360,23 +360,13 @@
|
|||
el.addEventListener("change", formElementChanged);
|
||||
}
|
||||
|
||||
function checkStatus() {
|
||||
setInterval(function() {
|
||||
if(activeRequests.size != 0) return;
|
||||
// From https://stackoverflow.com/a/50101022
|
||||
|
||||
const abort = new AbortController();
|
||||
const signal = abort.signal;
|
||||
|
||||
// 50 second timeout:
|
||||
const timeoutId = setTimeout(() => abort.abort(), 50000);
|
||||
|
||||
fetch(new Request("{% url 'status' access_code=access_code %}"
|
||||
+ (statusObj.hash != ""
|
||||
? statusObj.hash + "/"
|
||||
: "")),
|
||||
{signal})
|
||||
: "")))
|
||||
.then(response => {
|
||||
clearTimeout(timeoutId);
|
||||
if(response.status === 304) {
|
||||
// TODO Just skip the next step?
|
||||
return statusObj;
|
||||
|
@ -391,14 +381,8 @@
|
|||
} else {
|
||||
statusObj = data;
|
||||
}
|
||||
})
|
||||
.then(checkStatus)
|
||||
.catch(() => {
|
||||
// If something went wrong, wait a few seconds before retrying.
|
||||
setTimeout(checkStatus, 5000);
|
||||
});
|
||||
}
|
||||
checkStatus();
|
||||
}, 5000);
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
|
|
@ -27,5 +27,7 @@ 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'),
|
||||
])),
|
||||
]
|
||||
|
|
|
@ -5,18 +5,12 @@ 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.conf import settings
|
||||
from django.db import transaction
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.views.decorators.http import require_safe, require_http_methods,\
|
||||
require_POST
|
||||
from django.urls import reverse, set_script_prefix
|
||||
from django.urls import reverse
|
||||
|
||||
from .forms import NewGameForm, JoinGameForm, PlayerFormSet
|
||||
from .models import Game, Player, Fear
|
||||
|
@ -294,22 +288,12 @@ def handle_game_request(request, game, update):
|
|||
res['value'] = current_value
|
||||
else:
|
||||
res = {'success': True}
|
||||
async_to_sync(get_channel_layer().group_send)(
|
||||
"%s_status" % game.access_code,
|
||||
{"type": "fear_tracker.invalidate_status"})
|
||||
return HttpResponse(json.dumps(res))
|
||||
|
||||
players = get_players_with_fear(game, current_phase, players)
|
||||
status_obj = game_status_object(game, current_phase, players)
|
||||
status_string = json.dumps(status_obj)
|
||||
|
||||
async_to_sync(get_channel_layer().group_send)(
|
||||
"%s_status" % game.access_code, {
|
||||
"type": "fear_tracker.hashcode_seen",
|
||||
"hashcode": status_obj['hash'],
|
||||
"status_string": status_string,
|
||||
})
|
||||
|
||||
for player in players.values():
|
||||
info = player.fear
|
||||
if not info:
|
||||
|
@ -340,63 +324,4 @@ def status(request, game, hashcode=None):
|
|||
return HttpResponse(status=HTTPStatus.NOT_MODIFIED)
|
||||
else:
|
||||
status_string = json.dumps(status_obj)
|
||||
async_to_sync(get_channel_layer().group_send)(
|
||||
"%s_status" % game.access_code, {
|
||||
"type": "fear_tracker.hashcode_seen",
|
||||
"hashcode": status_obj['hash'],
|
||||
"status_string": status_string,
|
||||
})
|
||||
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)
|
||||
await self.channel_layer.group_send(
|
||||
"%s_status" % self.access_code, {
|
||||
"type": "fear_tracker.hashcode_seen",
|
||||
"hashcode": self.hashcode,
|
||||
})
|
||||
|
||||
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_hashcode_seen(self, event):
|
||||
if self.hashcode != event["hashcode"]:
|
||||
if event["status_string"]:
|
||||
body = event["status_string"].encode('utf-8')
|
||||
await self.send_response(200, body)
|
||||
await self.disconnect()
|
||||
await self.channel_layer.group_send(
|
||||
"%s_status" % self.access_code, {
|
||||
"type": "fear_tracker.invalidate_status",
|
||||
})
|
||||
|
||||
async def fear_tracker_invalidate_status(self, event):
|
||||
# get script_prefix for reverse()
|
||||
script_prefix = self.scope.get("root_path", "") or ""
|
||||
if settings.FORCE_SCRIPT_NAME:
|
||||
script_prefix = settings.FORCE_SCRIPT_NAME
|
||||
set_script_prefix(script_prefix)
|
||||
|
||||
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'))
|
||||
])
|
||||
await self.http_disconnect(None)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import fear_tracker.routing
|
||||
from channels.routing import ProtocolTypeRouter
|
||||
|
||||
application = fear_tracker.routing.application
|
||||
# No async routing currently; just default sync http.
|
||||
application = ProtocolTypeRouter({})
|
||||
|
|
|
@ -31,7 +31,6 @@ ALLOWED_HOSTS = []
|
|||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'channels',
|
||||
'fear_tracker',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
|
@ -83,12 +82,6 @@ DATABASES = {
|
|||
}
|
||||
}
|
||||
|
||||
CHANNEL_LAYERS = {
|
||||
"default": {
|
||||
"BACKEND": "channels.layers.InMemoryChannelLayer"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
||||
|
|
Loading…
Reference in New Issue
Block a user