-
Notifications
You must be signed in to change notification settings - Fork 2
/
socketHandler.py
108 lines (88 loc) · 3.52 KB
/
socketHandler.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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Add to SockJS-tornado the multi-room support
"""
from sockjs.tornado import SockJSConnection
from jsonParser import Parser
from structure import Struct
import logging
try:
import json
except ImportError:
import simplejson as json
# Limit import
__all__ = ["SockJSDefaultHandler", "SockJSRoomHandler"]
class SockJSDefaultHandler(SockJSConnection):
""" Default handler """
_parser = Parser()
def on_message(self, data):
""" Parsing data, and try to call responding message """
# Trying to parse response
data = json.loads(data)
if not data["name"] is None:
logging.debug("%s: receiving message %s" % (data["name"], data["data"]))
fct = getattr(self, "on_" + data["name"])
try:
res = fct(Struct(data["data"]))
except:
# We try without Struct item (on transaction request this can happend)
res = fct(data["data"])
if res is not None:
self.write_message(res)
else:
logging.error("SockJSDefaultHandler: data.name was null")
def publish(self, name, data, userList):
""" Publish data """
# Publish data to all room users
self.broadcast(userList, {
"name": name,
"data": SockJSDefaultHandler._parser.encode(data)
})
class SockJSRoomHandler(SockJSDefaultHandler):
""" Room handler """
_room = {}
def _gcls(self):
""" Get the classname """
return self.__class__.__name__
def join(self, _id):
""" Join a room """
if not SockJSRoomHandler._room.has_key(self._gcls() + _id):
SockJSRoomHandler._room[self._gcls() + _id] = set()
SockJSRoomHandler._room[self._gcls() + _id].add(self)
def leave(self, _id):
""" Leave a room """
if SockJSRoomHandler._room.has_key(self._gcls() + _id):
SockJSRoomHandler._room[self._gcls() + _id].remove(self)
if len(SockJSRoomHandler._room[self._gcls() + _id]) == 0:
del SockJSRoomHandler._room[self._gcls() + _id]
def getRoom(self, _id):
""" Retrieve a room from it's id """
if SockJSRoomHandler._room.has_key(self._gcls() + _id):
return SockJSRoomHandler._room[self._gcls() + _id]
return None
def publishToRoom(self, roomId, name, data, userList=None):
""" Publish to given room data submitted """
if userList is None:
userList = self.getRoom(roomId)
# Publish data to all room users
logging.debug("%s: broadcasting (name: %s, data: %s, number of users: %s)" % (self._gcls(), name, data, len(userList)))
self.broadcast(userList, {
"name": name,
"data": SockJSRoomHandler._parser.encode(data)
})
def publishToOther(self, roomId, name, data):
""" Publish to only other people than myself """
tmpList = self.getRoom(roomId)
# Select everybody except me
userList = [x for x in tmpList if x is not self]
self.publishToRoom(roomId, name, data, userList)
def publishToMyself(self, roomId, name, data):
""" Publish to only myself """
self.publishToRoom(roomId, name, data, [self])
def isInRoom(self, _id):
""" Check a given user is in given room """
if SockJSRoomHandler._room.has_key(self._gcls() + _id):
if self in SockJSRoomHandler._room[self._gcls() + _id]:
return True
return False