def on_message(self, message): entity = Message.from_dict(json.loads(message)) self.application.db.messages.insert_one(entity.__dict__) conn = ToRedisClient() conn.connect(host="redis") def publish_message(channel,message): conn.publish(channel,message) self.io_loop.add_timeout(time.time(), partial(publish_message,self.channel,format_entity(entity.__dict__)))
class Handler(RequestHandler): @asynchronous def get(self): self.client = Client() self.client.connect() self.client.subscribe("foo", callback=self.on_receive) def on_receive(self, msg): """ New message, close out connection. """ msg_type, msg_channel, msg = msg if msg_type == b"message": self.finish({"message": msg.decode()})
class Handler(RequestHandler): @asynchronous def get(self): self.client = Client() self.client.connect() self.client.subscribe("foo", callback=self.on_receive) def on_receive(self, msg): """ New message, close out connection. """ msg_type, msg_channel, msg = msg if msg_type == "message": self.finish({"message": msg})
async def get_grouped_count(group_type, content_id): """ Sends document id and group type to redis and returns page view count as response. """ group_value = get_group_value(group_type) if group_value is None: return 0 redis = Client() redis.connect(config.HOST, config.PORT) response = await gen.Task(redis.zcard, "{0}:{1}".format(group_value, content_id)) return response
def test_subscribe(self): """ Tests a subscription message """ # conn = redis.Redis() conn = Client() conn.connect() def publish_message(): conn.publish("foo", "bar") self.io_loop.add_timeout(time.time() + 0.5, publish_message) response = self.fetch("/") # blocks self.assertEqual(response.code, 200)
class RedisWebSocket(tornado.websocket.WebSocketHandler): client = None user = None channel = None io_loop = tornado.ioloop.IOLoop.instance() def open(self): # Get user and channel self.user = self.get_argument('user', None) self.channel = self.get_argument('channel', None) # new access self.application.db.access.insert_one(Access.connect(self.user,self.channel).__dict__) # get all messages messages = self.application.db.messages.find({"channel" : self.channel}).sort("$natural",pymongo.DESCENDING) output = [format_entity(msg) for msg in messages] for message in reversed(output): self.write_message(message) # subscribe to channel self.client = ToRedisClient() self.client.connect(host="redis") self.client.subscribe(self.channel, callback=self.on_receive) def on_receive(self,msg): msg_type, msg_channel, msg = msg if msg_type == b"message": self.write_message(eval(msg)) # client.write_message(message) def on_message(self, message): entity = Message.from_dict(json.loads(message)) self.application.db.messages.insert_one(entity.__dict__) conn = ToRedisClient() conn.connect(host="redis") def publish_message(channel,message): conn.publish(channel,message) self.io_loop.add_timeout(time.time(), partial(publish_message,self.channel,format_entity(entity.__dict__))) # self.application.manager.notify(entity.channel,format_entity(entity.__dict__)) def on_close(self): self.application.db.access.insert_one(Access.disconnect(self.user, self.channel).__dict__) self.client.unsubscribe(self.channel)
class MessageHandler(WebSocketHandler): def __init__(self, *args, **kwargs): super(MessageHandler, self).__init__(*args, **kwargs) self.r_server = Redis() self.redis = Client() self.redis.connect() def get_current_user(self): user = self.get_secure_cookie("user") if user is None: return '' else: return user.strip('" ') def on_message(self, msg): msginfo = loads(msg) # listens for handshake from page self.channel = msginfo['user'] # need to split the rest off to new func so it can be asynchronous self.listen() def listen(self): # runs task given, with the yield required to get returned value # equivalent of callback/wait pairing from tornado.gen self.redis.subscribe(self.channel, callback=self.callback) # fight race condition by loading from redis after listen started oldmessages = self.r_server.lrange('%s:messages' % self.channel, 0, -1) if oldmessages is not None: for message in oldmessages: self.write_message(message) def callback(self, msg): if msg[0] == 'message': self.write_message(msg[2]) @engine def on_close(self): yield Task(self.redis.unsubscribe, self.channel) self.redis.disconnect()
# -*- coding: utf-8 -*- from tornado import httpclient from toredis import Client redis_client = Client() redis_client.connect('localhost') http_client = httpclient.AsyncHTTPClient()
import logging import tornado.ioloop from toredis import Client def test_auth(): # Assuming that 12345 is your redis pasword redis.auth('12345', after_auth) def after_auth(status): print 'Authentication status:', status assert status == 'OK' io_loop.stop() if __name__ == "__main__": logging.basicConfig() io_loop = tornado.ioloop.IOLoop.instance() redis = Client() redis.connect('localhost', callback=test_auth) io_loop.start()
class SessionHandler(object): """ Manage complete flight session. """ def __init__(self, session_id, vehicle_id, api_key, namespace, name, poi, height, clearance, wait_time=10., url=None): self.session_id = session_id self.vehicle_id = vehicle_id self.api_key = api_key self.ns = namespace self.name = name self.poi = poi # point of interest information. e.g. {'lat':45.,'long':65., 'alt':10.0} self.height = height # height at which the drone should fly self.clearance = clearance # distance away from PPOI self.wait_time = wait_time # drone will wait at users;s location for these many seconds self.url = url # stream endpoint # setup environment variables. self.api_base_url = 'https://dev.flytbase.com/rest/ros/' + self.ns self.header = { 'Authorization': 'Token ' + self.api_key, 'VehicleID': self.vehicle_id } self.status = -1 # set session status flag to 'initilized state' self.fuse = True # if fuse is false then the session will stay on hold. No call backs should execute. self.home = None self.target_loc = self.poi.copy( ) # later change this to 'clearance' meter distance away from POI in straight line path. # Initialize redis client self.redis = RedisClient() self.redis.connect('localhost') # instance of non blocking http client self.http_client = AsyncHTTPClient() self.init_redis_structs() @gen.engine def init_redis_structs(self): # initialize session structure and upload to redis server. No need to update this later session_struct = json.dumps({ "vehicle_id": self.vehicle_id, "session_key": "removed_key", "api_key": self.api_key, "ns": self.ns }) yield gen.Task(self.redis.set, self.session_id + "_info", session_struct) # initialize status structure for session on redis. This should be updated after state change. yield gen.Task(self.redis.set, self.session_id + "_status", self.status) # update sessions structure. No need to update this. cur_sessions = yield gen.Task(self.redis.get, "sessions") try: cur_sessions = json.loads(cur_sessions) updated_sessions = cur_sessions.copy() updated_sessions[self.session_id] = {"session_key": "removed"} yield gen.Task(self.redis.set, "sessions", updated_sessions) except ValueError: print "session JSON decode error" @gen.coroutine def run_mission(self): # todo "make sure app is initialized" yield gen.sleep(5.0) if self.status == -1 and self.fuse: print "Session Handler: Initialized, starting stream" success, resp = yield self.start_stream() if success: print "Session Handler: Request success: ", resp else: print "Session Handler: Request failed: ", resp self.status = 0 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) if self.status == 0 and self.fuse: # save home location. self.home = yield self.get_drone_state() # Update the target clearance distance away from POI offset_loc = get_offset_location(self.home['lat'], self.home['long'], self.poi['lat'], self.poi['long'], self.clearance) self.target_loc = { 'lat': offset_loc[0], 'long': offset_loc[1], 'alt': self.poi['alt'] } print "Session Handler: taking off" success, resp = yield self.take_off(3.0) if success: print "Request success: ", resp else: print "Request failed: ", resp # todo handle takeoff failure self.status = 1 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) if self.status == 1 and self.fuse: print "Session Handler: Attaining mission height and correcting heading" # todo check that self.home is populated success, resp = yield self.attain_global_setpoint( self.home['lat'], self.home['long'], self.height, 3) if success: print "Session Handler: Request success: ", resp else: print "Session Handler: Request failed: ", resp # todo handle this case dist, ang = dist_ang_betn_coordinates(self.home['lat'], self.home['long'], self.poi['lat'], self.poi['long']) delta_ang = ang - self.home['yaw'] success, resp = yield self.attain_yaw_sp(delta_ang) if success: print "Session Handler: Request success: ", resp else: print "Session Handler: Request failed: ", resp # todo handle this case self.status = 2 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) if self.status == 2 and self.fuse: print "Session Handler: Moving to goal" success, resp = yield self.attain_global_setpoint( self.target_loc['lat'], self.target_loc['long'], self.height, 3) if success: print "Session Handler: Request success: ", resp else: print "Session Handler: Request failed: ", resp self.status = 3 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) if self.status == 3 and self.fuse: # print "Session Handler: pointing towards user" # Nothing here self.status = 4 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) # don't change mission number now, 4 will be used to allow 3rd party access. if self.status == 4 and self.fuse: print "Session Handler: Waiting at goal", self.wait_time yield gen.sleep(self.wait_time) print "Session Handler: confirming lock" access_lock = yield self.check_access_lock(4, 100) print "Session Handler: acquired lock" if not access_lock: print "FATAL!" self.status = 5 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) # continue only if status code is 5 in database. If it is 100 (foreign access) # then wait for 10 more seconds before checking if self.status == 5 and self.fuse: print "Session Handler: Moving back to home" # success, resp = yield self.global_sp(self.home['lat'], self.home['long'], self.height, 0., False, False) success, resp = yield self.attain_global_setpoint( self.home['lat'], self.home['long'], self.height, 3) if success: print "Session Handler: Request success: ", resp else: print "Session Handler: Request failed: ", resp self.status = 6 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) if self.status == 6 and self.fuse: print "Session Handler: landing" success, resp = yield self.land() if success: print "Session Handler: Request success: ", resp else: print "Session Handler: Request failed: ", resp self.status = 7 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) if self.status == 7 and self.fuse: print "Session Handler: stopping stream" success, resp = yield self.stop_stream() if success: print "Session Handler: Request success: ", resp else: print "Session Handler: Request failed: ", resp self.status = 8 yield gen.Task(self.redis.set, self.session_id + "_status", self.status) # set_drone free yield self.close_session() @gen.coroutine def check_access_lock(self, wait_case, foreign_case): """return True when access lock is released""" # TOdo repeat only 3 times. current_state = yield gen.Task(self.redis.get, self.session_id + "_status") if current_state == str(wait_case): raise gen.Return(True) if current_state == str(foreign_case): print "Session Handler: will try to acquire lock again in 10 secs." yield gen.sleep(10.) res = yield self.check_access_lock(wait_case, foreign_case) raise gen.Return(res) @gen.coroutine def attain_global_setpoint(self, lat, long, height, max_retries=3, max_error_retries=3, r_count=0, re_count=0): success, resp = yield self.global_sp(lat, long, height, 0., False, False) if success: # print "Request success: ", resp max_error_retries = 0 try: resp_dec = json.loads(resp) if not resp_dec['success']: if r_count <= max_retries: r_count += 1 print "Session Handler: Target not achieved, retrying: retry no. ", r_count success, resp = yield self.attain_global_setpoint( lat, long, height, max_retries, max_error_retries, r_count, re_count) raise gen.Return((success, resp)) else: raise gen.Return((False, resp)) raise gen.Return((True, resp)) except ValueError, KeyError: print "drone GPOS sp API json response decode failed", success, resp raise gen.Return((False, resp)) else:
return None key = custom_vars["1"][0] value = custom_vars["1"][1] if value == "": return None return value def make_app(): return tornado.web.Application([ (r"/capture", MainHandler), # serve pikik tag (r"/static/(.*)", tornado.web.StaticFileHandler, {'path': STATIC_DIR}), ]) def set_database(): redis.select(config.getint('redis','index')) if __name__ == "__main__": app = make_app() app.listen(config.getint('server','port')) redis = Client() redis.connect(host=config.get('redis','hostname'), port=config.getint('redis','port'), callback=set_database) tornado.ioloop.IOLoop.current().start()
if message_type == 'landing:track:change': for participant in RouterConnection.participants: if participant.user_id == 'anonymous': participant.send(message_data) elif message_type == 'admin:': user_id = data.get('user_id', None) for participant in RouterConnection.participants: if participant.user_id == user_id: participant.send(message_data) application = tornado.web.Application( sockjs.tornado.SockJSRouter(RouterConnection, '/sock').urls ) if __name__ == '__main__': parse_command_line() import logging logging.getLogger().setLevel(logging.DEBUG) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port, address=options.host) client = Client() client.connect() client.subscribe('tornado_events', callback=tornado_events) tornado.ioloop.IOLoop.instance().start()
import logging import tornado.ioloop from tornado import gen from toredis import Client @gen.engine def test(): # Authenticate first status = yield gen.Task(redis.auth, "12345") assert status == "OK" # Select database status = yield gen.Task(redis.select, "0") assert status == "OK" print "Success" io_loop.stop() if __name__ == "__main__": logging.basicConfig() io_loop = tornado.ioloop.IOLoop.instance() redis = Client() redis.connect("localhost", callback=test) io_loop.start()
import logging import tornado.ioloop from tornado import gen from toredis import Client @gen.engine def test(): # Authenticate first status = yield gen.Task(redis.auth, '12345') assert status == 'OK' # Select database status = yield gen.Task(redis.select, '0') assert status == 'OK' print('Success') io_loop.stop() if __name__ == "__main__": logging.basicConfig() io_loop = tornado.ioloop.IOLoop.instance() redis = Client() redis.connect('localhost', callback=test) io_loop.start()
class WebSocketClient(WebSocketClientBase): def __init__(self, drone_info, drone_vec, sub_topics, throttle_rate=6000): self.api_key = drone_info["api_key"] # API key to talk with drone. self.vehicle_id = drone_info["vehicle_id"] # vehicle ID of the drone. self.namespace = drone_info["namespace"] # namespace of the drone self.topics_subscribed = [] self.drone_vec = drone_vec # drone status vector that will be updated. self.topics_to_subscribe = sub_topics self.msglib = MsgStructs(self.namespace, throttle_rate) self.redis = RedisClient() self.redis.connect('localhost') super(WebSocketClient, self).__init__() def _on_message(self, msg): try: res = json.loads(msg) ioloop.IOLoop.instance().add_callback(partial(self.parse_msg, res)) except ValueError: print "json decoding failed" def _on_connection_success(self): print('Drone Connected! ', self.vehicle_id) deadline = time.time() + 1 ioloop.IOLoop().instance().add_timeout( deadline, functools.partial(self.subscribe_to_topics)) def _on_connection_close(self): print('Connection closed!') def _on_connection_error(self, exception): print('Connection error: %s', exception) def subscribe_to_topics(self): for topic in self.topics_to_subscribe: self.topics_subscribed.append(topic) ioloop.IOLoop.instance().add_callback( partial(self.send, json.dumps(self.msglib.sub_msg(topic)))) # TODO remove debug statement # ioloop.IOLoop().instance().add_timeout(time.time()+10, functools.partial(self.stop_client)) def stop_client(self): # unsubscribe from the data. for topic in self.topics_subscribed: self.send(json.dumps(self.msglib.get_unsub_msg(topic))) # call close method self.close() def parse_msg(self, msg): if isinstance(msg, dict): if 'op' in msg.keys(): if msg['op'] == 'publish': # print msg word6 = msg['topic'][-6:] if word6 == "global": lat = msg['msg']['latitude'] lon = msg['msg']['longitude'] alt = msg['msg']['altitude'] # print lat, lon, "global" self.redis.set( self.vehicle_id + '_gpos', json.dumps({ "lat": lat, "long": lon, "alt": alt })) if word6 == "/local": x = msg['msg']['twist']['linear']['x'] y = msg['msg']['twist']['linear']['y'] z = msg['msg']['twist']['linear']['z'] yaw = msg['msg']['twist']['angular']['z'] # print x,y,z, "local" self.redis.set( self.vehicle_id + '_lpos', json.dumps({ "x": x, "y": y, "z": z, "yaw": yaw })) if word6 == "attery": percent = msg['msg']['percentage'] # print percent*100, " % battery" self.redis.set(self.vehicle_id + '_batt', json.dumps({"percent": percent})) if word6 == "_euler": yaw = msg['msg']['twist']['linear']['z'] # print percent*100, " % battery" self.redis.set(self.vehicle_id + '_imu', json.dumps({"yaw": yaw}))
import operator from tornado import gen from toredis import Client as RedisClient from tornado.web import Application, RequestHandler, asynchronous import sys from tornado import ioloop import json import time import requests from helper import WebSocketClient, dist_bet_coordinates, DroneRemoteAccess from session import SessionHandler ### Initialize redis client redis_main = RedisClient() redis_main.connect('localhost') ### set parameters drone_status_update_rate = 4000 # data will be updated every T mili seconds. sub_topics = ["gpos", "lpos", 'imu', "battery"] # topics to be subscribed def init_redis_structures(drone_list): """ update initial structures on redis server """ counter = 0 drone_dict = {} for drone in drone_list: counter += 1 name = "SFRD00" + str(counter)
class ChatSocketHandler(UserMixin, tornado.websocket.WebSocketHandler): cache_size = 30 commands_client = Client() pub_client = Client() def open(self): # FIXME: make chat_channel dynamic self.chat_channel = "chat" self.chat_userset = chat_userset_key(self.chat_channel) self.from_user = self.get_current_user()['name'] host, port = options.redis.split(":") self.sub_client = Client() self.sub_client.connect(host, int(port)) logging.debug("Opened subscribe connection to redis for user=%s", self.from_user) # first add entered user in user_set, then subscribe to notifications def sadd_finished(resp): self.sub_client.subscribe(self.chat_channel, callback=self.on_redis_message) self.sub_client.sadd(self.chat_userset, self.from_user, callback=sadd_finished) logging.info("%s joined the chat", self.from_user) ChatSocketHandler.send_message(self.chat_channel, self.from_user, "joined the chat", system=True) def on_redis_message(self, msg): msg_type, msg_channel, msg = msg logging.debug("Got message from Redis: type=%s, channel=%s, msg=%s", msg_type, msg_channel, msg) if msg_type == b"message": # write message back to websocket self.write_message(json.loads(msg.decode())) def on_close(self): logging.info("%s left the chat", self.from_user) self.sub_client.srem(self.chat_userset, self.from_user) ChatSocketHandler.send_message(self.chat_channel, self.from_user, "left the chat", system=True) def on_message(self, message): logging.info("got message %r", message) ChatSocketHandler.send_message(self.chat_channel, self.from_user, message) @classmethod def update_lastmessages(cls, chat_channel, chat): cls.pub_client.lpush(chat_lastmessages_key(chat_channel), json.dumps(chat)) cls.pub_client.ltrim(chat_lastmessages_key(chat_channel), 0, cls.cache_size) @classmethod def last_messages(cls, chat_channel, callback): """get last messages""" if not cls.commands_client.is_connected(): host, port = options.redis.split(":") cls.commands_client.connect(host, int(port)) logging.debug("Opened commands connection to redis") def transform(response): json_resp = [json.loads(x.decode("utf8")) for x in response] callback(json_resp[::-1]) cls.commands_client.lrange(chat_lastmessages_key(chat_channel), 0, cls.cache_size, callback=transform) @classmethod def current_users(cls, chat_channel, callback): """get last messages""" if not cls.commands_client.is_connected(): host, port = options.redis.split(":") cls.commands_client.connect(host, int(port)) logging.debug("Opened commands connection to redis") def transform(response): json_resp = [x.decode("utf8") for x in response] callback(json_resp) cls.commands_client.smembers(chat_userset_key(chat_channel), callback=transform) @classmethod def send_message(cls, chat_channel, from_user, body, system=False): if not cls.pub_client.is_connected(): host, port = options.redis.split(":") cls.pub_client.connect(host, int(port)) logging.debug("Opened publish connection to redis") if not system: body = message_beautify(body) chat_msg = { "id": str(uuid.uuid4()), "from": from_user, "when": datetime.now().strftime("%Y-%m-%d %H:%M"), "body": body, "system": system, } cls.update_lastmessages(chat_channel, chat_msg) logging.debug("Broadcasting message %s", chat_msg) cls.pub_client.publish(chat_channel, json.dumps(chat_msg))
redis.get('test_key', callback=after_get) @gen.engine def test_gen(): """ ``gen.engine`` example """ # Set test_key2 with 10 result = yield gen.Task(redis.set, 'test_key2', 10) assert result == 'OK' # Increment test_key2. result = yield gen.Task(redis.incr, 'test_key2') assert result == 11 # Get test_key2 value. Redis will return string instead of number. result = yield gen.Task(redis.get, 'test_key2') assert result == '11' finish() if __name__ == "__main__": logging.basicConfig() redis = Client() redis.connect('localhost', callback=test_set) tornado.ioloop.IOLoop.instance().start()