groundwork for websockets in place (besides channel layers)

This commit is contained in:
iou1name 2018-08-15 17:41:51 -04:00
parent 67a65702a1
commit e885f9decc
6 changed files with 86 additions and 13 deletions

View File

@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock %} - Titivillus</title>
<link rel="stylesheet" type="text/css" href="{{ static('base.css') }}">
<script>

View File

@ -2,19 +2,49 @@
"""
Consumers available for the /quest websocket.
"""
import json
from channels.generic.websocket import WebsocketConsumer
from .events import events
class QuestConsumer(WebsocketConsumer):
"""
The main consumer for /quest websockets.
"""
def __init__(self, *args, **kwargs):
"""
Overriden method. Adds dictionary of events and functions to be
used by self.receive().
"""
self.events = events
super().__init__(*args, **kwargs)
def connect(self):
self.accept()
self.send('message: connected')
def disconnect(self):
def disconnect(self, close_code):
pass
def receive(self, text_data):
print(text_data)
self.send("message: lol}")
"""
Parses the received data as JSON and dispatches the appropirate
event handler.
"""
try:
data = json.loads(text_data)
except json.JSONDecodeError:
return
event = data.get('event')
if not event or event not in self.events.keys():
return
self.events[event](self, data.get('data'))
def send(self, event, data):
"""
Overridden method. If a dictionary is provided, it is converted
to JSON before sending it.
If a string is provided, it is sent out directly.
"""
data = json.dumps({'event': event, 'data': data})
super().send(text_data=data)

23
quest/events.py Normal file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env python3
"""
Individual functions for handling WebSocket events. Gets called by the
QuestConsumer object in consumers.py.
"""
import types
def message(socket, data):
"""
Gets called when the server receives a 'message' event.
"""
message = data.get('message')
print(message)
data = {}
data['message'] = message.upper()
socket.send('message', data)
events = {}
for obj in dir():
if type(locals()[obj]) == types.FunctionType:
events[locals()[obj].__name__] = locals()[obj]

View File

@ -3,9 +3,9 @@
{% block head %}
<link rel="stylesheet" type="text/css" href="{{ static('quest.css') }}">
<script>
var quest_id = {{ quest.id }};
var page_num = {{ page_num }};
var SCRIPT_NAME = '{{ request.META["SCRIPT_NAME"] }}';
const quest_id = {{ quest.id }};
const page_num = {{ page_num }};
const SCRIPT_NAME = '{{ request.META["SCRIPT_NAME"] }}';
</script>
<script type="text/javascript" src="{{ static('quest.js') }}"></script>
{% if request.user == quest.owner %}
@ -34,9 +34,9 @@
{% if post.post_type == "text" %}
<div class="questPost textPost">
{% elif post.post_type == "dice" %}
<div class="questPost dicePost{% if post == posts|last %} active_post{% endif %}">
<div class="questPost dicePost{% if post == posts|last %} activePost{% endif %}">
{% elif post.post_type == "poll" %}
<div class="questPost pollPost{% if post == posts|last %} active_post{% endif %}">
<div class="questPost pollPost{% if post == posts|last %} activePost{% endif %}">
{% endif %}
<div class="questPostMeta">
{{ post.timestamp.strftime('%Y-%m-%d %H:%M') }}
@ -44,9 +44,9 @@
{% if post.post_type == "text" %}
<br /><a href="javascript:void(0);" id="editPost-{{ post.id }}" onclick="edit_post({{ post.id }})">Edit</a>
<a href="javascript:void(0);" id="savePost-{{ post.id }}" onclick="save_post('{{ post.id }}')" style="display:none;">Save</a>
{% elif (post.post_type == "dice" or post.post_type == "poll") and post == posts|last %}
<br /><a href="javascript:void(0);" id="close_post_id-{{ post.id }}" onclick="close_post({{ post.id }})"{% if post.id != quest.open_post_id %} style="display:none;"{% endif %}>Close</a>
<a href="javascript:void(0);" id="open_post_id-{{ post.id }}" onclick="open_post({{ post.id }})"{% if post.id == quest.open_post_id %} style="display:none;"{% endif %}>Open</a>
{% elif post.post_type in ("dice", "poll") and post == posts|last %}
<br /><a href="javascript:void(0);" id="closePost-{{ post.id }}" onclick="close_post({{ post.id }})"{% if post.id != quest.open_post_id %} style="display:none;"{% endif %}>Close</a>
<a href="javascript:void(0);" id="openPost-{{ post.id }}" onclick="open_post({{ post.id }})"{% if post.id == quest.open_post_id %} style="display:none;"{% endif %}>Open</a>
{% endif %}
{% endif %}
</div>

View File

@ -1 +1,19 @@
var socket = new WebSocket('wss://' + document.domain + SCRIPT_NAME + '/ws/quest/' + quest_id + '/');
socket.oldSend = socket.send;
socket.send = function(event_title, data) {
data = JSON.stringify({event: event_title, data: data});
socket.oldSend.apply(this, [data]);
}
socket.events = {};
socket.onmessage = function(e) {
let data = JSON.parse(e.data);
let event = data.event;
data = data.data;
if (socket.events[event] === undefined) { return; }
socket.events[event](data);
}
socket.events['message'] = function(data) {
let message = data.message;
console.log(message);
}

View File

@ -4,6 +4,7 @@ ASGI entrypoint. Configures Django and then runs the application
defined in the ASGI_APPLICATION setting.
"""
import os
import django
from channels.routing import get_default_application