def route_management(): """ Manages the routes according to the request type: POST: Create new route DELETE: Remove existing route GET: List existing routes """ try: session_id = request.cookies[settings.HBP_COOKIE] except KeyError: session_id = 'demo' if request.method == 'GET': try: response = route_manager.get_route(session_id) return make_response(response, 200) except KeyError as e: return make_response(str(e), 404) if request.method == 'POST': if request.data is None: response = 'Error: Data must be provided for POST operations' log.error(response) return make_response(response, 401) json_data = json.loads(request.data) uri = json_data['uri'] log.info(1, 'Creating new route for ' + uri) response = route_manager.create_route(session_id, uri) return make_response(response, 201) else: return route_manager.delete_route(session_id)
def get_frame(self): """ Returns the current image generated by the remote rendering resource """ time.sleep(1 / HISS_FRAMES_PER_SECOND) try: response = requests.get( url=self.uri, timeout=HISS_REQUEST_TIMEOUT, headers={'Content-Type': 'application/json'}) status = response.status_code response.close() if status == 200: json_image_b64 = json.loads(response.content) return base64.decodestring(json_image_b64['data']) except requests.exceptions.ReadTimeout as e: log.error('Connection error: ' + str(e)) return None
def streamer(session_id, frame_grabber): """ Serves a given image stream :param session_id: Id of the session to stream :param frame_grabber: Implementation of the class in charge of fetching the images """ while route_manager.get_route(session_id): with application.app_context(): frame = None try: frame = frame_grabber.get_frame() # Optimization: Generate an MD5 for the current frame and push # it to the client only if it is different from the previous # one if frame is not None: frame_md5 = int(hashlib.md5(frame).hexdigest(), 16) if route_manager.get_frame_md5(session_id) != frame_md5: route_manager.set_frame_md5(session_id, frame_md5) yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') except KeyError: # Returns an empty frame frame = frame_not_found except ValueError as e: log.error(str(e)) except requests.exceptions as e: log.error('Removing route for session ' + str(session_id)) route_manager.delete_route(session_id) break except IOError: log.error('Lost connection with rendering resource. ' + 'Removing route for session ' + str(session_id)) route_manager.delete_route(session_id) break
def get_frame(self): """ Returns the current image generated by the remote rendering resource """ try: start = datetime.datetime.now() response = requests.get( url=self._uri, timeout=HISS_REQUEST_TIMEOUT, headers={'Content-Type': 'application/json'}) duration = datetime.datetime.now() - start delay = 1e6 / float(HISS_FRAMES_PER_SECOND) - duration.microseconds if delay > 0: import time time.sleep(delay / 1e6) status = response.status_code response.close() if status == 200: json_image_b64 = json.loads(response.content) return base64.decodestring(json_image_b64['data']) except requests.exceptions.ReadTimeout as e: log.error('Connection error: ' + str(e)) return None
def streamer(session_id, frame_grabber): """ Serves a given image stream :param session_id: Id of the session to stream :param frame_grabber: Implementation of the class in charge of fetching the images """ while route_manager.get_route(session_id): with application.app_context(): try: frame = frame_grabber.get_frame() # Optimization: Generate an MD5 for the current frame and push # it to the client only if it is different from the previous # one if frame is not None: push_frame = True if settings.HISS_STREAMING_OPTIMIZATION: frame_md5 = int(hashlib.md5(frame).hexdigest(), 16) if route_manager.get_frame_md5( session_id) != frame_md5: route_manager.set_frame_md5(session_id, frame_md5) else: push_frame = False if push_frame: yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') except KeyError: # Returns an empty frame yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame_not_found + b'\r\n') except ValueError as e: log.error(str(e)) except requests.exceptions as e: log.error('Removing route for session ' + str(session_id)) route_manager.delete_route(session_id) break except IOError: log.error('Lost connection with rendering resource. ' + 'Removing route for session ' + str(session_id)) route_manager.delete_route(session_id) break