/
server.py
128 lines (98 loc) · 3.95 KB
/
server.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
121
122
123
124
125
126
127
import logging
from os import path as op
import tornado.web
import tornadio
import tornadio.server
FLASH_POLICY_PORT = 843
WEB_SERVER_PORT = 8001
class ClientCollection:
@classmethod
def instance(cls):
if not hasattr(cls, "_instance"):
cls._instance = cls()
return cls._instance
@classmethod
def initialized(cls):
return hasattr(cls, "_instance")
def __init__(self):
self.users = {}
def add(self, name, client):
success = False
if name not in self.users:
self.users[name] = client
success = True
return success
def remove(self, name):
if name in self.users:
del self.users[name]
def get_clients(self, omitt_name):
clients = []
for name, client in self.users.iteritems():
if name != omitt_name:
clients.append((name, client))
return clients
def get_client_names(self):
return self.users.keys()
class ChatRoomHandler(tornado.web.RequestHandler):
def get(self):
username = self.get_argument("username", default=None, strip=True)
client_names = ClientCollection.instance().get_client_names()
# Make sure the username doesn't already exist
if username and username not in client_names:
self.render("chatroom.html", username=username)
else:
self.render("lobby.html")
class LobbyHandler(tornado.web.RequestHandler):
def get(self):
self.render("lobby.html")
class SocketIOConnection(tornadio.SocketConnection):
def __init__(self, *args, **kwargs):
tornadio.SocketConnection.__init__(self, *args, **kwargs)
self.username = None
def on_open(self, *args, **kwargs):
pass
def on_close(self):
client_collection = ClientCollection.instance()
clients = client_collection.get_clients(self.username)
for name, client in clients:
client.send({"remove_client": self.username})
client_collection.remove(self.username)
def on_message(self, message):
client_collection = ClientCollection.instance()
if "new_user" in message:
username = message["new_user"]
client_collection.add(username, self)
clients = client_collection.get_clients(username)
for name, client in clients:
# Add existing clients to this new one
self.send({"new_client": name})
# Send this new client to all existing ones
client.send({"new_client": username})
self.username = username
elif "new_message" in message and self.username:
clients = client_collection.get_clients(self.username)
for name, client in clients:
client.send(message)
if __name__ == "__main__":
logging.getLogger().setLevel(logging.WARNING)
root_dir = op.normpath(op.dirname(__file__))
static_path = op.join(root_dir, "static")
SocketIOConnectionRouter = tornadio.get_router(SocketIOConnection)
# Configure the Tornado application
application = tornado.web.Application(
[(r"/favicon.ico", tornado.web.StaticFileHandler, {"path":static_path}),
(r"/", LobbyHandler),
(r"/lobby.html", LobbyHandler),
(r"/chatroom.html", ChatRoomHandler),
SocketIOConnectionRouter.route()],
static_path = static_path,
enabled_protocols = ['websocket',
'flashsocket',
'xhr-multipart',
'xhr-polling'],
flash_policy_port = FLASH_POLICY_PORT,
flash_policy_file = op.join(static_path, 'flashpolicy.xml'),
socket_io_port = WEB_SERVER_PORT,
)
tornadio.server.SocketServer(application)
tornado.ioloop.IOLoop.instance().start()