This repository has been archived by the owner on Apr 3, 2019. It is now read-only.
forked from evilkost/brukva
-
Notifications
You must be signed in to change notification settings - Fork 163
/
app.py
120 lines (98 loc) · 4.1 KB
/
app.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from __future__ import print_function
import uuid
import json
from random import choice
import tornado.httpserver
import tornado.web
import tornado.websocket
import tornado.ioloop
import tornado.gen
import redis
import tornadoredis
import tornadoredis.pubsub
try:
import sockjs.tornado
except:
print('Please install the sockjs-tornado package to run this demo.')
exit(1)
# Use the synchronous redis client to publish messages to a channel
redis_client = redis.Redis()
# Create the tornadoredis.Client instance
# and use it for redis channel subscriptions
subscriber = tornadoredis.pubsub.SockJSSubscriber(tornadoredis.Client())
class IndexPageHandler(tornado.web.RequestHandler):
def get(self):
self.render("template.html", title="PubSub + SockJS Demo")
class SendMessageHandler(tornado.web.RequestHandler):
def _send_message(self, channel, msg_type, msg, user=None):
msg = {'type': msg_type,
'msg': msg,
'user': user}
msg = json.dumps(msg)
redis_client.publish(channel, msg)
def post(self):
message = self.get_argument('message')
from_user = self.get_argument('from_user')
to_user = self.get_argument('to_user')
if to_user:
self._send_message('private.{}'.format(to_user),
'pvt', message, from_user)
self._send_message('private.{}'.format(from_user),
'tvp', message, to_user)
else:
self._send_message('broadcast_channel', 'msg', message, from_user)
self.set_header('Content-Type', 'text/plain')
self.write('sent: %s' % (message,))
class MessageHandler(sockjs.tornado.SockJSConnection):
"""
SockJS connection handler.
Note that there are no "on message" handlers - SockJSSubscriber class
calls SockJSConnection.broadcast method to transfer messages
to subscribed clients.
"""
def _enter_leave_notification(self, msg_type):
broadcasters = list(subscriber.subscribers['broadcast_channel'].keys())
message = json.dumps({'type': msg_type,
'user': self.user_id,
'msg': '',
'user_list': [{'id': b.user_id,
'name': b.user_name}
for b in broadcasters]})
if broadcasters:
broadcasters[0].broadcast(broadcasters, message)
def _send_message(self, msg_type, msg, user=None):
if not user:
user = self.user_id
self.send(json.dumps({'type': msg_type,
'msg': msg,
'user': user}))
def on_open(self, request):
# Generate a user ID and name to demonstrate 'private' channels
self.user_id = str(uuid.uuid4())[:5]
self.user_name = (
choice(['John', 'Will', 'Bill', 'Ron', 'Sam', 'Pete']) +
' ' +
choice(['Smith', 'Doe', 'Strong', 'Long', 'Tall', 'Small']))
# Send it to user
self._send_message('uid', self.user_name, self.user_id)
# Subscribe to 'broadcast' and 'private' message channels
subscriber.subscribe(['broadcast_channel',
'private.{}'.format(self.user_id)],
self)
# Send the 'user enters the chat' notification
self._enter_leave_notification('enters')
def on_close(self):
subscriber.unsubscribe('private.{}'.format(self.user_id), self)
subscriber.unsubscribe('broadcast_channel', self)
# Send the 'user leaves the chat' notification
self._enter_leave_notification('leaves')
application = tornado.web.Application(
[(r'/', IndexPageHandler),
(r'/send_message', SendMessageHandler)] +
sockjs.tornado.SockJSRouter(MessageHandler, '/sockjs').urls)
if __name__ == '__main__':
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
print('Demo is running at 0.0.0.0:8888\n'
'Quit the demo with CONTROL-C')
tornado.ioloop.IOLoop.instance().start()