def websocket_to_django(self): try: while 1: if self.zmodemOO: self.zmodemOO = False x = self.channel.recv(2) if not len(x): return if x == b'OO': self.websocker.send(bytes_data=x) continue else: x += self.channel.recv(4096) else: x = self.channel.recv(4096) if not len(x): return if self.zmodem: if zmodemszend in x or zmodemrzend in x: self.zmodem = False if zmodemszend in x: self.zmodemOO = True self.websocker.send(bytes_data=x) else: if zmodemszstart in x or zmodemrzstart in x: self.zmodem = True self.websocker.send(bytes_data=x) else: try: data = x.decode('utf-8') except UnicodeDecodeError: # utf-8中文占3个字符,可能会被截断,需要拼接 try: x += self.channel.recv(1) data = x.decode('utf-8') except UnicodeDecodeError: try: x += self.channel.recv(1) data = x.decode('utf-8') except UnicodeDecodeError: print(traceback.format_exc()) data = x.decode('utf-8', 'ignore') # 拼接2次后还是报错则证明结果是乱码,强制转换 self.message['status'] = 0 self.message['message'] = data self.res += data message = json.dumps(self.message) if self.websocker.send_flag == 0: self.websocker.send(message) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)(self.websocker.group, { "type": "chat.message", "text": message, }) delay = round(time.time() - self.start_time, 6) self.res_asciinema.append(json.dumps([delay, 'o', data])) # 指定条结果或者指定秒数或者占用指定内存就保存一次 if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 or \ sys.getsizeof(self.res_asciinema) > 20971752: tmp = list(self.res_asciinema) self.res_asciinema = [] self.last_save_time = time.time() save_res(self.res_file, tmp) if self.tab_mode: tmp = data.split(' ') # tab 只返回一个命令时匹配 # print(tmp) if len(tmp) == 2 and tmp[1] == '' and tmp[0] != '': self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace(b'\x07', b'').decode() elif len(tmp) == 1 and tmp[0].encode() != b'\x07': # \x07 蜂鸣声 self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace(b'\x07', b'').decode() self.tab_mode = False if self.history_mode: # 不完善,只支持向上翻一个历史命令 if data.strip() != '': self.cmd_tmp = data self.history_mode = False except socket.timeout: self.message['status'] = 1 self.message['message'] = '由于长时间没有操作或者没有数据返回,连接已断开!' message = json.dumps(self.message) if self.websocker.send_flag == 0: self.websocker.send(message) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)(self.websocker.group, { "type": "chat.message", "text": message, }) self.close(send_message=False) except Exception: self.close()
def websocket_to_django(self): try: while 1: if self.zmodemOO: self.zmodemOO = False x = self.channel.recv(2) if not len(x): return if x == b'OO': self.websocker.send(bytes_data=x) continue else: x += self.channel.recv(BufferSize) else: x = self.channel.recv(BufferSize) if not len(x): return if self.zmodem: if zmodemszend in x or zmodemrzend in x: self.zmodem = False if zmodemszend in x: self.zmodemOO = True if zmodemcancel in x: self.zmodem = False self.channel.send('\n') self.websocker.send(bytes_data=x) else: if zmodemszstart in x or zmodemrzstart in x or zmodemrzestart in x or zmodemrzsstart in x \ or zmodemrzesstart in x: self.zmodem = True self.websocker.send(bytes_data=x) else: try: data = x.decode('utf-8') except UnicodeDecodeError: # utf-8中文占3个字符,可能会被截断,需要拼接 try: x += self.channel.recv(1) data = x.decode('utf-8') except UnicodeDecodeError: try: x += self.channel.recv(1) data = x.decode('utf-8') except UnicodeDecodeError: logger.error(traceback.format_exc()) data = x.decode( 'utf-8', 'ignore') # 拼接2次后还是报错则证明结果是乱码,强制转换 self.message['status'] = 0 self.message['message'] = data self.res += data message = json.dumps(self.message) if self.websocker.send_flag == 0: self.websocker.send(message) elif self.websocker.send_flag == 1: async_to_sync( self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "chat.message", "text": message, }) delay = round(time.time() - self.start_time, 6) self.res_asciinema.append( json.dumps([delay, 'o', data])) # 指定条结果或者指定秒数或者占用指定内存就保存一次 if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 or \ sys.getsizeof(self.res_asciinema) > 20971752: tmp = list(self.res_asciinema) self.res_asciinema = [] self.last_save_time = time.time() save_res(self.res_file, tmp) if self.enter: self.enter = False if not data.startswith( "\r\n"): # 回车后结果不以\r\n开头的肯定不是命令 self.cmd_tmp = '' else: if re.match( rb'^\r\n\s+\x1b.*$', x ): # 终端为 xterm,linux 等显示颜色类型时在 vi 编辑模式下回车 self.cmd_tmp = '' # elif x == b'\r\n': # todo 正常模式下 vi 文件会返回 \r\n ,终端为 dumb 类型时在 vi 编辑模式下回车也会返回 \r\n, # self.cmd_tmp = '' else: # 记录真正命令, rl 不支持中文命令 cmd_time = time.strftime( "%Y-%m-%d %H:%M:%S", time.localtime(int(time.time()))) cmd = self.rl.process_line( self.cmd_tmp.encode("utf-8")) if cmd is None: # 有可能 rl 库会返回 None,重试一次 mp_readline.TESTING = True self.rl = mp_readline.MpReadline() cmd = self.rl.process_line( self.cmd_tmp.encode("utf-8")) if cmd: self.cmd += cmd_time + "\t" + remove_control_chars( cmd) + '\n' else: if cmd is None: logger.error( "recv from server: {} \nerror command: {}" .format( x, self.cmd_tmp.encode( "utf-8"))) self.cmd += cmd_time + "\t" + remove_control_chars( self.cmd_tmp) + '\n' self.cmd_tmp = '' else: if self.tab_mode: # todo 兼容有问题 self.tab_mode = False if x == b'\x07': pass tmp = data.split(' ') # tab 只返回一个命令时匹配 if len(tmp) == 2 and tmp[ 1] == '' and tmp[0] != '': self.cmd_tmp = self.cmd_tmp + tmp[ 0].encode().replace(b'\x07', b'').decode() elif len(tmp) == 1 and tmp[0].encode( ) != b'\x07': # \x07 蜂鸣声 self.cmd_tmp = self.cmd_tmp + tmp[ 0].encode().replace(b'\x07', b'').decode() # 多次上下箭头查找历史命令返回数据中可能会包含 \x1b[1P 导致 rl 无法解析命令,具体原因没有深究 if self.history_mode: self.history_mode = False if x != b'' and x != b'\x07': x = re.sub(rb'\x1b\[\d+P', b'', x) self.cmd_tmp += x.decode("utf-8") if self.ctrl_c: # 取消命令 self.ctrl_c = False # if x == b'^C\r\n': if re.match(rb'^\^C\r\n[\s\S]*$', x) or re.match( rb'^\r\n[\s\S]*$', x): self.cmd_tmp = "" if self.ctrl_z: self.ctrl_z = False if re.match( rb'^[\s\S]*\[\d+\]\+\s+Stopped\s+\S+[\s\S]*$', x): self.cmd_tmp = "" except socket.timeout: self.message['status'] = 1 self.message['message'] = '由于长时间没有操作或者没有数据返回,连接已断开!' message = json.dumps(self.message) if self.websocker.send_flag == 0: self.websocker.send(message) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "chat.message", "text": message, }) self.close(send_message=False) except Exception: logger.info(traceback.format_exc()) self.close()
def websocket_to_django(self): try: while True: data = '' # read_very_eager 方法读取时会是无限循环,性能比较低 # data = self.tn.read_very_eager().decode('utf-8') # if not len(data): # continue # expect 使用正则匹配所有返回内容,还可以实现超时无返回内容断开连接 try: if len(self._buffer) >= 1: data = self._buffer[:4096] self._buffer = self._buffer[4096:] else: x, y, z = self.tn.expect([br'[\s\S]+'], timeout=terminal_exipry_time) self._buffer += z data = self._buffer[:4096] # 一次最多截取4096个字符 self._buffer = self._buffer[4096:] data = data.decode('utf-8') except UnicodeDecodeError: # utf-8中文占3个字符,可能会被截断,需要拼接 try: if len(self._buffer) >= 1: data += self._buffer[:1] self._buffer = self._buffer[1:] else: x, y, z = self.tn.expect( [br'[\s\S]+'], timeout=terminal_exipry_time) if len(z) > 1: self._buffer += z data += self._buffer[:1] self._buffer = self._buffer[1:] else: data += z data = data.decode('utf-8') except UnicodeDecodeError: try: if len(self._buffer) >= 1: data += self._buffer[:1] self._buffer = self._buffer[1:] else: x, y, z = self.tn.expect( [br'[\s\S]+'], timeout=terminal_exipry_time) if len(z) > 1: self._buffer += z data += self._buffer[:1] self._buffer = self._buffer[1:] else: data += z data = data.decode('utf-8') except UnicodeDecodeError: print(traceback.format_exc()) data = data.decode( 'utf-8', 'ignore') # 拼接2次后还是报错则证明结果是乱码,强制转换 if not len(data): raise socket.timeout self.message['status'] = 0 self.message['message'] = data self.res += data message = json.dumps(self.message) if self.websocker.send_flag == 0: self.websocker.send(message) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "chat.message", "text": message, }) delay = round(time.time() - self.start_time, 6) self.res_asciinema.append(json.dumps([delay, 'o', data])) # 指定条结果或者指定秒数或者占用指定大小内存就保存一次 if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 or \ sys.getsizeof(self.res_asciinema) > 2097152: tmp = list(self.res_asciinema) self.res_asciinema = [] self.last_save_time = time.time() save_res(self.res_file, tmp) if self.tab_mode: tmp = data.split(' ') # tab 只返回一个命令时匹配 # print(tmp) if len(tmp) == 2 and tmp[1] == '' and tmp[0] != '': self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace( b'\x07', b'').decode() elif len(tmp ) == 1 and tmp[0].encode() != b'\x07': # \x07 蜂鸣声 self.cmd_tmp = self.cmd_tmp + tmp[0].encode().replace( b'\x07', b'').decode() self.tab_mode = False if self.history_mode: # 不完善,只支持向上翻一个历史命令 # print(data) if data.strip() != '': self.cmd_tmp = data self.history_mode = False except socket.timeout: self.message['status'] = 1 self.message['message'] = '由于长时间没有操作或者没有数据返回,连接已断开!' message = json.dumps(self.message) if self.websocker.send_flag == 0: self.websocker.send(message) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "chat.message", "text": message, }) self.close(send_message=False) except Exception: print(traceback.format_exc()) self.close()
def websocket_to_django(self): try: while 1: # read_very_eager 方法读取时会是无限循环,性能比较低 # data = self.tn.read_very_eager().decode('utf-8') # if not len(data): # continue # expect 使用正则匹配所有返回内容,还可以实现超时无返回内容断开连接 if len(self._buffer) >= 1: x = self._buffer[:BufferSize] self._buffer = self._buffer[BufferSize:] else: n, y, z = self.tn.expect([br'[\s\S]+'], timeout=terminal_exipry_time) self._buffer += z x = self._buffer[:BufferSize] # 一次最多截取 BufferSize 个字符 self._buffer = self._buffer[BufferSize:] if not len(x): raise socket.timeout try: data = x.decode('utf-8') except UnicodeDecodeError: # utf-8中文占3个字符,可能会被截断,需要拼接 try: if len(self._buffer) >= 1: x += self._buffer[:1] self._buffer = self._buffer[1:] else: n, y, z = self.tn.expect( [br'[\s\S]+'], timeout=terminal_exipry_time) if len(z) > 1: self._buffer += z x += self._buffer[:1] self._buffer = self._buffer[1:] else: x += z data = x.decode('utf-8') except UnicodeDecodeError: try: if len(self._buffer) >= 1: x += self._buffer[:1] self._buffer = self._buffer[1:] else: n, y, z = self.tn.expect( [br'[\s\S]+'], timeout=terminal_exipry_time) if len(z) > 1: self._buffer += z x += self._buffer[:1] self._buffer = self._buffer[1:] else: x += z data = x.decode('utf-8') except UnicodeDecodeError: data = x.decode('utf-8', 'ignore') # 拼接2次后还是报错则证明结果是乱码,强制转换 self.message['status'] = 0 self.message['message'] = data self.res += data message = json.dumps(self.message) if self.websocker.send_flag == 0: self.websocker.send(message) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "chat.message", "text": message, }) delay = round(time.time() - self.start_time, 6) self.res_asciinema.append(json.dumps([delay, 'o', data])) # 指定条结果或者指定秒数或者占用指定大小内存就保存一次 if len(self.res_asciinema) > 2000 or int(time.time() - self.last_save_time) > 60 or \ sys.getsizeof(self.res_asciinema) > 2097152: tmp = list(self.res_asciinema) self.res_asciinema = [] self.last_save_time = time.time() save_res(self.res_file, tmp) if self.enter: self.enter = False if not data.startswith("\r\n"): # 回车后结果不以\r\n开头的肯定不是命令 self.cmd_tmp = '' else: if re.match(rb'^\r\n\s+\x1b.*$', x): # 终端为 xterm,linux 等显示颜色类型时在 vi 编辑模式下回车 self.cmd_tmp = '' # elif x == b'\r\n': # todo 正常模式下 vi 文件会返回 \r\n ,终端为 dumb 类型时在 vi 编辑模式下回车也会返回 \r\n, # self.cmd_tmp = '' else: # 记录真正命令, rl 不支持中文命令 cmd_time = time.strftime( "%Y-%m-%d %H:%M:%S", time.localtime(int(time.time()))) cmd = self.rl.process_line( self.cmd_tmp.encode("utf-8")) if not cmd: # 有可能 rl 库会返回 None,重试一次 mp_readline.TESTING = True self.rl = mp_readline.MpReadline() cmd = self.rl.process_line( self.cmd_tmp.encode("utf-8")) if cmd: self.cmd += cmd_time + "\t" + remove_control_chars( cmd) + '\n' else: logger.error( "recv from server: {} \nerror command: {}". format(x, self.cmd_tmp.encode("utf-8"))) self.cmd += cmd_time + "\t" + remove_control_chars( self.cmd_tmp) + '\n' self.cmd_tmp = '' else: if self.tab_mode: # todo 兼容有问题 self.tab_mode = False tmp = data.split(' ') # tab 只返回一个命令时匹配 # print(tmp) if len(tmp) == 2 and tmp[1] == '' and tmp[0] != '': self.cmd_tmp = self.cmd_tmp + tmp[0].encode( ).replace(b'\x07', b'').decode() elif len(tmp) == 1 and tmp[0].encode( ) != b'\x07': # \x07 蜂鸣声 self.cmd_tmp = self.cmd_tmp + tmp[0].encode( ).replace(b'\x07', b'').decode() # 多次上下箭头查找历史命令返回数据中可能会包含 \x1b[1P 导致 rl 无法解析命令,具体原因没有深究 if self.history_mode: self.history_mode = False if x != b'' and x != b'\x07': x = re.sub(rb'\x1b\[\d+P', b'', x) self.cmd_tmp += x.decode("utf-8") if self.ctrl_c: # 取消命令 self.ctrl_c = False # if x == b'^C\r\n': if re.match(rb'^\^C\r\n[\s\S]*$', x) or re.match( rb'^\r\n[\s\S]*$', x): self.cmd_tmp = "" if self.ctrl_z: self.ctrl_z = False if re.match( rb'^[\s\S]*\[\d+\]\+\s+Stopped\s+\S+[\s\S]*$', x): self.cmd_tmp = "" except socket.timeout: self.message['status'] = 1 self.message['message'] = '由于长时间没有操作或者没有数据返回,连接已断开!' message = json.dumps(self.message) if self.websocker.send_flag == 0: self.websocker.send(message) elif self.websocker.send_flag == 1: async_to_sync(self.websocker.channel_layer.group_send)( self.websocker.group, { "type": "chat.message", "text": message, }) self.close(send_message=False) except Exception: logger.error(traceback.format_exc()) self.close()