def open(self, chat_id): sockets.add(self) redis.sadd("chat:%s:sockets:%s" % (self.chat_id, self.session_id), self.id) print "socket opened:", self.id, self.chat.url, self.user.username try: kick_check(redis, self) except KickedException: self.write_message(json.dumps({"exit": "kick"})) self.close() return # Subscribe self.channels = { "chat": "channel:%s" % self.chat_id, "user": "******" % (self.chat_id, self.user_id), "typing": "channel:%s:typing" % self.chat_id, } if self.chat.type == "pm": self.channels["pm"] = "channel:pm:%s" % self.user_id self.redis_listen() # Send backlog. try: after = int(self.request.query_arguments["after"][0]) except (KeyError, IndexError, ValueError): after = 0 messages = redis.zrangebyscore("chat:%s" % self.chat_id, "(%s" % after, "+inf") self.write_message(json.dumps({ "chat": self.chat.to_dict(), "messages": [json.loads(_) for _ in messages], })) join_message_sent = join(redis, self.db, self) self.joined = True # Send userlist if nothing was sent by join(). if not join_message_sent: self.write_message(json.dumps({"users": get_userlist(self.db, redis, self.chat)})) self.db.commit()
def messages(): try: after = int(request.form["after"]) except (KeyError, ValueError): after = 0 # Look for stored messages first, and only subscribe if there aren't any. messages = g.redis.zrangebyscore("chat:%s" % g.chat_id, "(%s" % after, "+inf") if "joining" in request.form or g.joining: db_connect() get_chat_user() return jsonify({ "users": get_userlist(g.db, g.redis, g.chat), "chat": g.chat.to_dict(), "messages": [json.loads(_) for _ in messages], }) elif len(messages) != 0: message_dict = { "messages": [json.loads(_) for _ in messages] } return jsonify(message_dict) pubsub = g.redis.pubsub() # Channel for general chat messages. pubsub.subscribe("channel:%s" % g.chat_id) # Channel for messages aimed specifically at you - kicks, bans etc. pubsub.subscribe("channel:%s:%s" % (g.chat_id, g.user_id)) # Get rid of the database connection here so we're not hanging onto it # while waiting for the redis message. db_commit() db_disconnect() for msg in pubsub.listen(): if msg["type"] == "message": # The pubsub channel sends us a JSON string, so we return that # instead of using jsonify. resp = make_response(msg["data"]) resp.headers["Content-type"] = "application/json" pubsub.close() return resp