def __receiver_loop(self): """ Main loop listening for incoming data. """ log.info("Starting receiver loop") try: while self.running: try: while self.running: frames = self.__read() for frame in frames: f = utils.parse_frame(frame) if self.__auto_decode: f.body = decode(f.body) self.process_frame(f, frame) except exception.ConnectionClosedException: if self.running: self.notify('disconnected') # # Clear out any half-received messages after losing connection # self.__recvbuf = b'' self.running = False break finally: self.cleanup() finally: with self.__receiver_thread_exit_condition: self.__receiver_thread_exited = True self.__receiver_thread_exit_condition.notifyAll() log.info("Receiver loop ended")
def __read(self): """ Read the next frame(s) from the socket. """ fastbuf = BytesIO() while self.running: try: try: c = self.receive() except exception.InterruptedException: log.debug("socket read interrupted, restarting") continue except Exception: c = b'' if len(c) == 0: raise exception.ConnectionClosedException() fastbuf.write(c) if b'\x00' in c: break elif c == b'\x0a': # heartbeat (special case) return [ c, ] self.__recvbuf += fastbuf.getvalue() fastbuf.close() result = [] if len(self.__recvbuf) > 0 and self.running: while True: pos = self.__recvbuf.find(b'\x00') if pos >= 0: frame = self.__recvbuf[0:pos] preamble_end = frame.find(b'\n\n') if preamble_end >= 0: content_length_match = BaseTransport.__content_length_re.search( decode(frame[0:preamble_end])) if content_length_match: content_length = int( content_length_match.group('value')) content_offset = preamble_end + 2 frame_size = content_offset + content_length if frame_size > len(frame): # # Frame contains NUL bytes, need to read more # if frame_size < len(self.__recvbuf): pos = frame_size frame = self.__recvbuf[0:pos] else: # # Haven't read enough data yet, exit loop and wait for more to arrive # break result.append(frame) self.__recvbuf = self.__recvbuf[pos + 1:] else: break return result
def __receiver_loop(self): """ Main loop listening for incoming data. """ log.info("Starting receiver loop") try: while self.running: try: while self.running: frames = self.__read() for frame in frames: f = utils.parse_frame(frame) if self.__auto_decode: f.body = decode(f.body) self.process_frame(f, frame) except exception.ConnectionClosedException: if self.running: self.notify('disconnected') # # Clear out any half-received messages after losing connection # self.__recvbuf = b'' self.running = False break finally: self.cleanup() finally: self.__receiver_thread_exit_condition.acquire() self.__receiver_thread_exited = True self.__receiver_thread_exit_condition.notifyAll() self.__receiver_thread_exit_condition.release() log.info("Receiver loop ended")
def parse_frame(frame): """ Parse a STOMP frame into a Frame object. :param frame: the frame received from the server (as a string) """ f = Frame() if frame == b'\x0a': f.cmd = 'heartbeat' return f mat = PREAMBLE_END_RE.search(frame) preamble_end = -1 if mat: preamble_end = mat.start() if preamble_end == -1: preamble_end = len(frame) preamble = decode(frame[0:preamble_end]) preamble_lines = LINE_END_RE.split(preamble) f.body = frame[preamble_end + 2:] # Skip any leading newlines first_line = 0 while first_line < len(preamble_lines) and len(preamble_lines[first_line]) == 0: first_line += 1 # Extract frame type/command f.cmd = preamble_lines[first_line] # Put headers into a key/value map f.headers = parse_headers(preamble_lines, first_line + 1) return f
def parse_frame(frame): """ Parse a STOMP frame into a Frame object. :param frame: the frame received from the server (as a string) """ f = Frame() if frame == b'\x0a': f.cmd = 'heartbeat' return f mat = PREAMBLE_END_RE.search(frame) preamble_end = -1 if mat: preamble_end = mat.start() if preamble_end == -1: preamble_end = len(frame) preamble = decode(frame[0:preamble_end]) preamble_lines = LINE_END_RE.split(preamble) f.body = frame[preamble_end + 2:] # Skip any leading newlines first_line = 0 while first_line < len(preamble_lines) and len( preamble_lines[first_line]) == 0: first_line += 1 # Extract frame type/command f.cmd = preamble_lines[first_line] # Put headers into a key/value map f.headers = parse_headers(preamble_lines, first_line + 1) return f
def __read(self): """ Read the next frame(s) from the socket. """ fastbuf = StringIO() while self.running: try: try: c = self.receive() except InterruptedException: log.debug("socket read interrupted, restarting") continue c = decode(c) except Exception: _, e, _ = sys.exc_info() c = '' if len(c) == 0: raise exception.ConnectionClosedException() fastbuf.write(c) if '\x00' in c: break elif c == '\x0a': # heartbeat (special case) return c self.__recvbuf += fastbuf.getvalue() fastbuf.close() result = [] if len(self.__recvbuf) > 0 and self.running: while True: pos = self.__recvbuf.find('\x00') if pos >= 0: frame = self.__recvbuf[0:pos] preamble_end = frame.find('\n\n') if preamble_end >= 0: content_length_match = Transport.__content_length_re.search(frame[0:preamble_end]) if content_length_match: content_length = int(content_length_match.group('value')) content_offset = preamble_end + 2 frame_size = content_offset + content_length if frame_size > len(frame): # # Frame contains NUL bytes, need to read more # if frame_size < len(self.__recvbuf): pos = frame_size frame = self.__recvbuf[0:pos] else: # # Haven't read enough data yet, exit loop and wait for more to arrive # break result.append(frame) self.__recvbuf = self.__recvbuf[pos+1:] else: break return result
def parse_frame(frame): """ Parse a STOMP frame into a Frame object. :param bytes frame: the frame received from the server (as a byte string) :rtype: Frame """ f = Frame() if frame == b'\x0a': f.cmd = 'heartbeat' return f mat = PREAMBLE_END_RE.search(frame) if mat: preamble_end = mat.start() body_start = mat.end() else: preamble_end = len(frame) body_start = preamble_end preamble = decode(frame[0:preamble_end]) preamble_lines = LINE_END_RE.split(preamble) preamble_len = len(preamble_lines) f.body = frame[body_start:] # Skip any leading newlines first_line = 0 while first_line < preamble_len and len(preamble_lines[first_line]) == 0: first_line += 1 if first_line >= preamble_len: return None # Extract frame type/command f.cmd = preamble_lines[first_line] # Put headers into a key/value map f.headers = parse_headers(preamble_lines, first_line + 1) return f
def parse_frame(frame): """ Parse a STOMP frame into a (frame_type, headers, body) tuple, where frame_type is the frame type as a string (e.g. MESSAGE), headers is a map containing all header key/value pairs, and body is a string containing the frame's payload. \param frame the frame received from the server (as a string) """ f = Frame() if frame == b'\x0a': f.cmd = 'heartbeat' return f mat = PREAMBLE_END_RE.search(frame) preamble_end = -1 if mat: preamble_end = mat.start() if preamble_end == -1: preamble_end = len(frame) preamble = decode(frame[0:preamble_end]) preamble_lines = LINE_END_RE.split(preamble) f.body = frame[preamble_end + 2:] # Skip any leading newlines first_line = 0 while first_line < len(preamble_lines) and len( preamble_lines[first_line]) == 0: first_line += 1 # Extract frame type/command f.cmd = preamble_lines[first_line] # Put headers into a key/value map f.headers = parse_headers(preamble_lines, first_line + 1) return f
def parse_frame(frame): """ Parse a STOMP frame into a (frame_type, headers, body) tuple, where frame_type is the frame type as a string (e.g. MESSAGE), headers is a map containing all header key/value pairs, and body is a string containing the frame's payload. \param frame the frame received from the server (as a string) """ f = Frame() if frame == b'\x0a': f.cmd = 'heartbeat' return f mat = PREAMBLE_END_RE.search(frame) preamble_end = -1 if mat: preamble_end = mat.start() if preamble_end == -1: preamble_end = len(frame) preamble = decode(frame[0:preamble_end]) preamble_lines = LINE_END_RE.split(preamble) f.body = frame[preamble_end + 2:] # Skip any leading newlines first_line = 0 while first_line < len(preamble_lines) and len(preamble_lines[first_line]) == 0: first_line += 1 # Extract frame type/command f.cmd = preamble_lines[first_line] # Put headers into a key/value map f.headers = parse_headers(preamble_lines, first_line + 1) return f