def send_stream(self): while self.is_online: self.is_send_stream = True try: yield self.img_socket.recv(config.img_size) except Exception as e: func.write_logs('图片传输异常:' + str(e)) yield b'' return b''
def _thread(): while True: if self.is_send_stream: self.is_send_stream = False time.sleep(4) if not self.is_send_stream: self.cmd_socket.sendall(config.cmds['stop_pi_stream']) func.write_logs('停止转发图片') #break self.is_check_stream_start = False func.write_logs('图片发送检测线程退出')
def resolve_user_cmd(user_id, target, cmd, env, user_connect, pi_connect): def _str(cmds, msg): if env == USER_ENV_PY_ADMIN or env == USER_ENV_WEB_ADMIN: return msg return cmds user = user_connect.get_user(user_id) if not user: return _str(config.cmds['user_not login'], '拒绝访问!用户[%s]未登录或者不存在!' % user_id) # 发向树莓派的命令 if target == config.cmds['app_to_pi']: if not user.is_pi_connected: return _str(config.cmds['pi_not_connect'], '数据发送失败!用户[%s]对应的树莓派未连接!' % user_id) user.pi.cmd_socket.sendall( (target + config.cmds['cmd_split'] + cmd).encode()) if user.pi.cmd_socket.recv( config.max_cmds_length) == config.cmds['server_ok']: return _str(config.cmds['server_ok'].decode(), '成功向树莓派发送数据:' + cmd) else: return _str(config.cmds['server_error'].decode(), '向树莓派发送数据失败!') # 发向服务器的命令 elif target == config.cmds['app_to_server']: # 获取树莓派数据 if cmd == config.cmds['data']: func.write_logs('用户[%s]请求获取树莓派数据' % user.id) if not user.is_pi_connected: return _str(config.cmds['pi_not_connect'], '操作失败!树莓派未连接!') user.pi.cmd_socket.sendall(config.cmds['get_pi_data']) data_size = user.pi.cmd_socket.recv(10) try: size = int(data_size) except ValueError: return _str(config.cmds['server_error'].decode(), '数据请求出错,无法获取数据大小 (' + str(data_size) + ')') else: data = func.get_all_socket_data(user.pi.cmd_socket, size).decode() return _str(data, '树莓派的数据:\n' + data) # 温度数据包 elif cmd == config.cmds['get_temperature']: func.write_logs('用户[%s]请求温度数据包' % user.id) data = tools.read_file(config.data_package_file, config.data_package['temperature']) return _str(data, '温度数据包:' + data) else: return _str(config.cmds['server_error'].decode(), '用户[%s]提供了无法识别的服务器命令:' % cmd) else: return _str(config.cmds['invalid_cmd'], '无法识别的APP命令头部:' + target)
def connect(self, user_id, user_password, user_env): func.write_logs('用户请求连接!') user_info = UserInfo.get_user_info_by_id(user_id) if user_info: if user_info.password == user_password: user = User(user_id, user_env) user.user_info = user_info user.is_online = True user.pi = self.pi_connect.get_pi(user_info.pi_id) if user.pi: user.is_pi_connected = True user.pi.is_user_connected = True user.pi.user = user self.add_user(user) return user
def disconnect(self, pi): if not self.get_pi(pi.id): return if pi.user: pi.user.is_pi_connected = False pi.user.pi = None pi.is_online = False self.online_pi.remove(pi) try: pi.connect_socket.close() pi.cmd_socket.close() pi.img_socket.close() except Exception as e: func.write_logs('断开树莓派%s时 Exception: %s' % (pi.id, str(e))) func.write_logs('树莓派%s已下线。' % pi.id)
def _thread(): try: func.write_logs('启动树莓派%s的连接检测线程' % pi.id) while pi.is_online: try: pi.connect_socket.sendall(b'pi') time.sleep(3) except ConnectionResetError: func.write_logs('树莓派%s关掉了一个现有连接... <ConnectionReset>' % pi.id) self.disconnect(pi) except Exception as e: func.write_logs('树莓派连接异常中断, 已断开连接!<%s>' % str(e)) raise except Exception as e: func.write_logs('异常:' + str(e) + ' [检测与树莓派的连接状态]线程退出') self.disconnect(pi) func.write_logs('树莓派%s的连接守护线程退出' % pi.id)
def check_stream(self): if self.is_check_stream_start: return self.is_check_stream_start = True func.write_logs('开始运行图片发送检测线程') def _thread(): while True: if self.is_send_stream: self.is_send_stream = False time.sleep(4) if not self.is_send_stream: self.cmd_socket.sendall(config.cmds['stop_pi_stream']) func.write_logs('停止转发图片') #break self.is_check_stream_start = False func.write_logs('图片发送检测线程退出') tools.start_thread(_thread)
def __thread(pi_info): func.write_logs('验证通过,与树莓派建立tcp连接中 ...') tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcp_socket.settimeout(config.connect_timeout) tcp_socket.bind(('', config.ali_tcp_port)) tcp_socket.listen(3) try: cmd_socket, addr = tcp_socket.accept() cmd_socket.sendall(config.cmds['server_ok']) img_socke, addr = tcp_socket.accept() img_socke.sendall(config.cmds['server_ok']) connect_socket, addr = tcp_socket.accept() connect_socket.sendall(config.cmds['server_ok']) except socket.timeout: print('TCP连接超时,树莓派连接失败!') return func.write_logs('TCP连接创建成功!') pi = Pi(pi_info.id) pi.pi_info = pi_info pi.cmd_socket = cmd_socket pi.img_socket = img_socke pi.connect_socket = connect_socket pi.user = self.user_connect.get_user(pi_info.user_id) pi.is_online = True self.add_pi(pi) if pi.user: pi.is_user_connected = True pi.user.is_pi_connected = True pi.user.pi = pi self.keep_pi_connect(pi) func.write_logs('树莓派%s与服务器连接成功。' % pi.id)
def _thread(): func.write_logs('树莓派连接线程已启动!') udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.bind(('', config.ali_udp_port)) while True: try: info, addr = udp_socket.recvfrom(config.max_cmds_length) func.write_logs('接收到树莓派连接:' + str(addr)) func.write_logs('验证树莓派信息:%s ...' % info) try: pi_info = PiInfo.get_pi_info_by_id(info.decode()) except UnicodeDecodeError: pi_info = None if pi_info: udp_socket.sendto(config.cmds['server_ok'], addr) tools.start_thread(__thread, (pi_info, )) else: udp_socket.sendto(config.cmds['server_error'], addr) func.write_logs('树莓派信息失败!没有匹配! ' + str(info)) except Exception as e: func.write_logs('树莓派连接线程检测出异常:' + str(e))
def __init__(self): func.write_logs('创建UserConnect对象!') self.online_user = [] # 在线的用户 self.pi_connect = None
def add_pi(self, pi): _pi = self.get_pi(pi.id) if _pi: func.write_logs('该树莓派已经连接,先断开之前的连接 ... ') self.disconnect(_pi) self.online_pi.append(pi)
def connect(self): func.write_logs('树莓派连接正在准备中 ... ') # 连接检验线程 def __thread(pi_info): func.write_logs('验证通过,与树莓派建立tcp连接中 ...') tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcp_socket.settimeout(config.connect_timeout) tcp_socket.bind(('', config.ali_tcp_port)) tcp_socket.listen(3) try: cmd_socket, addr = tcp_socket.accept() cmd_socket.sendall(config.cmds['server_ok']) img_socke, addr = tcp_socket.accept() img_socke.sendall(config.cmds['server_ok']) connect_socket, addr = tcp_socket.accept() connect_socket.sendall(config.cmds['server_ok']) except socket.timeout: print('TCP连接超时,树莓派连接失败!') return func.write_logs('TCP连接创建成功!') pi = Pi(pi_info.id) pi.pi_info = pi_info pi.cmd_socket = cmd_socket pi.img_socket = img_socke pi.connect_socket = connect_socket pi.user = self.user_connect.get_user(pi_info.user_id) pi.is_online = True self.add_pi(pi) if pi.user: pi.is_user_connected = True pi.user.is_pi_connected = True pi.user.pi = pi self.keep_pi_connect(pi) func.write_logs('树莓派%s与服务器连接成功。' % pi.id) # 接收树莓派请求线程 def _thread(): func.write_logs('树莓派连接线程已启动!') udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.bind(('', config.ali_udp_port)) while True: try: info, addr = udp_socket.recvfrom(config.max_cmds_length) func.write_logs('接收到树莓派连接:' + str(addr)) func.write_logs('验证树莓派信息:%s ...' % info) try: pi_info = PiInfo.get_pi_info_by_id(info.decode()) except UnicodeDecodeError: pi_info = None if pi_info: udp_socket.sendto(config.cmds['server_ok'], addr) tools.start_thread(__thread, (pi_info, )) else: udp_socket.sendto(config.cmds['server_error'], addr) func.write_logs('树莓派信息失败!没有匹配! ' + str(info)) except Exception as e: func.write_logs('树莓派连接线程检测出异常:' + str(e)) tools.start_thread(_thread)