/
campr.py
103 lines (86 loc) · 3.13 KB
/
campr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""
This module contains classes that contribute to the Campr class, which
is a tornado app that handles all of Campr's functionality.
Note that the bulk of Campr is handled by a Django app found in frontend/.
The Tornado app delegates most of the HTTP request to this, and only
handles the pubsub part of the app itself.
"""
import os
import os.path as op
os.environ['DJANGO_SETTINGS_MODULE'] = 'frontend.settings'
import json
import tornadio
import tornadio.router
import tornadio.server
import tornado.ioloop
import tornado.web
import tornado.wsgi
import django.core.handlers.wsgi
from django.conf import settings
from frontend.events.models import Message, Checkin
class CamprConnection(tornadio.SocketConnection):
"""
The Campr socket connection class. Its methods define what we
do when different kinds of events come in over the socket.
"""
participants = set()
def on_open(self, *args, **kwargs):
"""
Handles when we get a new connection in over socket.IO
"""
self.participants.add(self)
def on_message(self, messageStr):
"""
Handles when we receive a new message from a participant over socket.IO
"""
message = json.loads(messageStr)
if message['type'] == 'update':
message = Message(
checkin=Checkin.objects.get(id=message['checkin_id']),
message=message['message'])
message.save()
for p in self.participants:
p.send('{0}'.format(messageStr))
def on_close(self):
"""
What to do when a participant's connection closes.
"""
self.participants.remove(self)
class Campr():
"""
The Campr tornado application.
"""
def __init__(self, port):
"""
Constructor.
"""
tornado_settings = {
"static_path": os.path.join(os.path.dirname(__file__), "static"),
"socket_io_port": port,
'flash_policy_port': 843,
'enabled_protocols': ['websocket',
'flashsocket',
'xhr-multipart',
'xhr-polling'],
}
# The wrapper around our Django app.
wsgi_app = tornado.wsgi.WSGIContainer(django.core.handlers.wsgi.WSGIHandler())
self.application = tornado.web.Application([
(r'/', tornado.web.FallbackHandler, {'fallback': wsgi_app}),
(r'/static/(.*)', tornado.web.StaticFileHandler, {'path': op.join(settings.ROOT, 'static')}),
tornadio.get_router(CamprConnection).route(),
(r'.*', tornado.web.FallbackHandler, {'fallback': wsgi_app}),
], **tornado_settings)
self.server = None
def start(self):
"""
Starts the Campr tornado app.
"""
io_loop = tornado.ioloop.IOLoop.instance()
tornadio.server.SocketServer(self.application, io_loop=io_loop)
def stop(self):
"""
Stops the Campr tornado app.
"""
io_loop = tornado.ioloop.IOLoop.instance()
io_loop.add_timeout(2, tornado.ioloop.IOLoop.instance().stop)