def run(args, schema, secret): try: if tn_globals.IsInteractive: tn_globals.Prompt = PromptSession() # Create secure channel with default credentials. channel = None if args.ssl: opts = (('grpc.ssl_target_name_override', args.ssl_host),) if args.ssl_host else None channel = grpc.secure_channel(args.host, grpc.ssl_channel_credentials(), opts) else: channel = grpc.insecure_channel(args.host) # Call the server stream = pbx.NodeStub(channel).MessageLoop(gen_message(schema, secret, args)) # Read server responses for msg in stream: if tn_globals.Verbose: stdoutln("\r<= " + to_json(msg)) if msg.HasField("ctrl"): handle_ctrl(msg.ctrl) elif msg.HasField("meta"): what = [] if len(msg.meta.sub) > 0: what.append("sub") if msg.meta.HasField("desc"): what.append("desc") if msg.meta.HasField("del"): what.append("del") if len(msg.meta.tags) > 0: what.append("tags") stdoutln("\r<= meta " + ",".join(what) + " " + msg.meta.topic) if tn_globals.WaitingFor and tn_globals.WaitingFor.await_id == msg.meta.id: if 'varname' in tn_globals.WaitingFor: tn_globals.Variables[tn_globals.WaitingFor.varname] = msg.meta tn_globals.WaitingFor = None elif msg.HasField("data"): stdoutln("\n\rFrom: " + msg.data.from_user_id) stdoutln("Topic: " + msg.data.topic) stdoutln("Seq: " + str(msg.data.seq_id)) if msg.data.head: stdoutln("Headers:") for key in msg.data.head: stdoutln("\t" + key + ": "+str(msg.data.head[key])) stdoutln(json.loads(msg.data.content)) elif msg.HasField("pres"): # 'ON', 'OFF', 'UA', 'UPD', 'GONE', 'ACS', 'TERM', 'MSG', 'READ', 'RECV', 'DEL', 'TAGS' what = pb.ServerPres.What.Name(msg.pres.what) stdoutln("\r<= pres " + what + " " + msg.pres.topic) elif msg.HasField("info"): switcher = { pb.READ: 'READ', pb.RECV: 'RECV', pb.KP: 'KP' } stdoutln("\rMessage #" + str(msg.info.seq_id) + " " + switcher.get(msg.info.what, "unknown") + " by " + msg.info.from_user_id + "; topic=" + msg.info.topic + " (" + msg.topic + ")") else: stdoutln("\rMessage type not handled" + str(msg)) except grpc.RpcError as err: # print(err) printerr("gRPC failed with {0}: {1}".format(err.code(), err.details())) except Exception as ex: printerr("Request failed: {0}".format(ex)) # print(traceback.format_exc()) finally: printout('Shutting down...') channel.close() if tn_globals.InputThread != None: tn_globals.InputThread.join(0.3)
def gen_message(scheme, secret, args): """Client message generator: reads user input as string, converts to pb.ClientMsg, and yields""" random.seed() id = random.randint(10000,60000) # Asynchronous input-output tn_globals.InputThread = threading.Thread(target=stdin, args=(tn_globals.InputQueue,)) tn_globals.InputThread.daemon = True tn_globals.InputThread.start() msg = hiMsg(id, args.background) if tn_globals.Verbose: stdoutln("\r=> " + to_json(msg)) yield msg if scheme != None: id += 1 login = lambda:None setattr(login, 'scheme', scheme) setattr(login, 'secret', secret) setattr(login, 'cred', None) msg = loginMsg(id, login, args) if tn_globals.Verbose: stdoutln("\r=> " + to_json(msg)) yield msg print_prompt = True while True: try: if not tn_globals.WaitingFor and tn_globals.InputQueue: id += 1 inp = tn_globals.InputQueue.popleft() if inp == 'exit' or inp == 'quit' or inp == '.exit' or inp == '.quit': # Drain the output queue. while pop_from_output_queue(): pass return pbMsg, cmd = serialize_cmd(inp, id, args) print_prompt = tn_globals.IsInteractive if isinstance(cmd, list): # Push the expanded macro back on the command queue. tn_globals.InputQueue.extendleft(reversed(cmd)) continue if pbMsg != None: if not tn_globals.IsInteractive: sys.stdout.write("=> " + inp + "\n") sys.stdout.flush() if cmd.synchronous: cmd.await_ts = time.time() cmd.await_id = str(id) tn_globals.WaitingFor = cmd if not hasattr(cmd, 'no_yield'): if tn_globals.Verbose: stdoutln("\r=> " + to_json(pbMsg)) yield pbMsg elif not tn_globals.OutputQueue.empty(): pop_from_output_queue() print_prompt = tn_globals.IsInteractive else: if print_prompt: sys.stdout.write("tn> ") sys.stdout.flush() print_prompt = False if tn_globals.WaitingFor: if time.time() - tn_globals.WaitingFor.await_ts > AWAIT_TIMEOUT: stdoutln("Timeout while waiting for '{0}' response".format(tn_globals.WaitingFor.cmd)) tn_globals.WaitingFor = None time.sleep(0.1) except Exception as err: stdoutln("Exception in generator: {0}".format(err))