话不多说,先上图。

调试端口容器内部telnet不通 端口 telnet_telnet 命令

这里以调用RPC框架dubbo接口为例,每次我们都是在测试某个接口或者验证某个dubbo接口得时候,都是写个controller去进行curl,而想要手动调用dubbo接口得时候,都需要先查ip,端口号,然后进入dubbo命令行界面,输入invoke得到结果,这些重复得工作一遍又一遍,对于可爱得程序员和美丽得测试妹子来说,这是在浪费我们深度交流得宝贵时间,不可忍耐。

在《重构:改善既有代码的设计》第三章代码的坏味道中,第一个被批判的就是DuplicatedCode(重复代码),可见重复性是万恶之源,在代码中不可忍,重复的手工操作更是要拒绝。

那么有没有什么可以办法解决呢?别问,问就是没有。但是对于左手python右手java的我们来说,怎么可以说没有。下面就是笔者使用python脚本编写得使用telnet调用dubbo接口得简单封装,在此基础稍加修饰就可以改成更加通用得程序,之后我们就可以再写不用写controller和调用dubbo接口去查看接口情况了,测试妹子也可以更愉快得去写单元测试了。

以下代码适用于python2.x和python3.x,由于linux发行版本身附带的软件(如RedHat系的包管理器dnf就是用python写的)需要python环境,所以linux默认就拥有python2.7得环境,对于不熟悉python得同学,也能直接复制粘贴直接linux运行。由于从这里复制后直接在linux运行会语法错误,建议赋值到记事本将空格和注释全部去掉,获取一行一行的复制进去后就可以了。

话不多说,人生苦短,python走起。

import jsonimport telnetlibdef invoke(method_call_str, ip='127.0.0.1', port=20880):    """    类似在dubbo linux中的invoke的操作    :param method_call_str:    :param ip: ip地址    :param port: 端口号    :return:    """    prompt = 'dubbo>'    coding = 'utf-8'    # 创建telnet类对象    conn = telnetlib.Telnet()    # 连接dubbo接口地址    conn.open(ip, port)    # cmd命令格式: 接口全名字.方法名(参数1,参数2,参数3...参数n)    # write方法就是模拟我们在linux上的操作,通过telnet或者nc -nvv ip port一样发起dubbo的请求的执行步骤,参数和单独使用telnet一致    # 我们输入telnet后要换行的    conn.write(b'\n')    # 然后等待我们会出现dubbo>的标签头    data = conn.read_until(prompt.encode())    # 然后将我们的调用接口的信息发给dubbo 然后输入命令后要换行执行    conn.write(method_call_str.encode() + b"\n")    # 然后等待我们会出现dubbo>的标签头    data = conn.read_until(prompt.encode())    # 然后将结果中result之后的部分取出来,就是一个返回的json对象    data = data.decode("utf-8", "ignore").split('result')[-1].split('\r\n')[0].split(': ')[-1].strip()    return data# invoke 包的全限定名.方法名(参数1,参数2,参数3......)methon_info=r'invoke xxx.xxx("xxx")'#你得ip地址ip = 'xxx'# 你的dubbo端口号port = 20888data=invoke(methon_info, ip, port)data=json.loads(data)# 返回结果就是json对象# 然后就是根据具体的json对象去取具体想要的数据了code=data.get('code')# 这一步如果是python3.x 要改为print(code)print code

结束语

其实dubbo命令调用接口,最繁琐的就是invoke后的接口参数,他本身是将字符串进行反序列化构造参数。比如用户输入的指令为invoke com.mjcr.telnet.call('1111'), 那么他会将invoke识别成command命令,然后将invoke后面的东西解析成message去调用。

@SPIpublic interface TelnetHandler{    // 第一步 这里面会将我们传入的json串转为JSON对象    String telnet(Channel channel, String message) throws RemotingException;}