class TestHandler(WebMessageHandler): """ Testing out sending data to arbitrary websockets """ def get(self): ws_message = "I like websockets" to_user_id = self.get_argument('to_user_id') if not to_user_id: body = "enter arg ?to_user_id=X" else: conn_ids = WSSession.get_active_conn_ids(to_user_id) for conn_id in conn_ids: send_message_through_ws(ws_message, conn_id, self.message.sender) body = "sending a websocket frame to conn_ids ", conn_ids self.set_body(body) return self.render() ### ### Websockets helper functions ### def send_message_through_ws(msg, conn_id, sender_uuid): """ send a message through a ws """ m2conn = Mongrel2Connection(*IPC_SOCKET_TUPLE) conn_id = recipient ## Need a session data lookup #recipient_session = ws_data = ws_string_to_data(msg) m2conn.send(sender_uuid, conn_id, ws_data) def ws_string_to_data(msg): """ Build a websocket frame from a string of the message """ ws_frame = Frame(opcode=OPCODE_TEXT, body=msg, masking_key=os.urandom(4), fin=1) ws_data = ws_frame.build() return ws_data ### ### Simple WS Session model ### class WSSession(Document, EtherealMongoMixin): """ A Session that stores map between user id and potentially open websocket connection ids (given from mongrel2) """ user_id = IntField(required=True) active_conn_ids = ListField(IntField()) last_updated = DateTimeField() coll_name = "ws_session" @classmethod def update_session(cls, user_id, conn_id, safe=True): # avoid duplicates by checking for them first # (allows race conditions, but whatever) if isinstance(user_id, basestring): user_id = int(user_id) sesh = cls.get_active_conn_ids(user_id) if len(sesh) > 0 and sesh[-1] == conn_id: pass else: cls.mdbc().update({'user_id': user_id}, {'$push': {'active_conn_ids': [conn_id]}}, upsert=True, safe=safe) # update dt return cls.mdbc().update({'user_id': user_id}, {'$set': {'last_updated': datetime.datetime.now()}}, safe=safe) @classmethod def get_active_conn_ids(cls, user_id): if isinstance(user_id, basestring): user_id = int(user_id) sesh = cls.mdbc().find_one({'user_id': user_id}) or {} return sesh.get('active_conn_ids', [])