def start_streaming(self, timeout=10): ''' Starts data streaming from the server, using the following algorithm: 1. Waits until start/data message arrives or timeout is over 2. If start message arrived, initializes buffer 3. Spawns a background process for data streaming 4. Releases Parameters ---------- timeout : float, optional time to wait for a start message (in seconds) ''' if self.is_streaming: raise Exception('already streaming') self.logger.info('waiting for an rda start message...') hdr = rdadefs.rda_msg_hdr_t() then = time.time() now = time.time() while now - then < timeout: n = self.sock.recv_into(hdr) rdatools.check_received(n, hdr) if not rdatools.validate_rda_guid(hdr): self.logger.warning('packet with unknown GUID reveived') if hdr.nType == rdadefs.RDA_START_MSG: self.start_msg = rdatools.rda_read_start_msg(self.sock, hdr) self.logger.info('start message received, ' + \ rdatools.startmsg2string(self.start_msg)) break elif hdr.nType == rdadefs.RDA_FLOAT_MSG and self.start_msg: self.sock.recv(hdr.nSize - c.sizeof(hdr)) self.logger.info('trying to resume previous session...') break else: self.sock.recv(hdr.nSize - c.sizeof(hdr)) self.logger.info('skipped package (type = %s)' % hdr.nType) now = time.time() if not self.__buf.is_initialized: self.logger.info('initializing buffer...') self.__buf.initialize(int(self.start_msg.nChannels), self.buffer_size, self.buffer_window, self.data_dtype) self.logger.info('spawning a streamer process...') self.__streamer = Streamer(self.q, self.sock.fileno(), self.__buf.raw) self.__streamer._daemonic = True self.__streamer.start()
def run(self): ''' The main streaming loop. ''' cmd = self.__get_cmd() hdr = rdadefs.rda_msg_hdr_t() self.logger.info('started streaming') # Ignore Ctrl+C. The process is run in the daemonic mode, so if the # Client terminates, the streamer will be terminated anyway. This # ignoring however, allows for custom Ctrl+C handling in the # Client process to gracefully stop both the Client and the Streamer signal.signal(signal.SIGINT, signal.SIG_IGN) # stream until there's a stop command while cmd != 'stop': n = self.sock.recv_into(hdr) rdatools.check_received(n, hdr) # check for a proper packet ID if not rdatools.validate_rda_guid(hdr): self.logger.warning('packet with unknown GUID reveived') if hdr.nType == rdadefs.RDA_FLOAT_MSG: msg = rdatools.rda_read_data_msg(self.sock, hdr, self.__buf.nChannels) self.__put_datablock(msg) # skip the weird undocumented package elif hdr.nType == 10000: self.sock.recv(hdr.nSize - c.sizeof(hdr)) elif hdr.nType == rdadefs.RDA_STOP_MSG: self.logger.info('stop message received, stopping...') self.q.put('stop') time.sleep(.5) else: self.sock.recv(hdr.nSize - c.sizeof(hdr)) self.logger.info('skipped package (type = %s)' % hdr.nType) cmd = self.__get_cmd() self.logger.info('stopped streaming') # execute the last command before exiting cmd = self.__get_cmd() self.__execute_cmd(cmd)