示例#1
0
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)
示例#2
0
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))