You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by "xcorpio (GitHub)" <gi...@apache.org> on 2019/01/07 09:21:37 UTC

[GitHub] [incubator-dubbo] xcorpio opened issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

## 背景
我在写一个测试 Dubbo 接口的通用工具,基本流程就是  `HTTP/JSON` -> `泛化调用(我实现的工具)` -> `Dubbo Providers`。按照[使用泛化调用](http://dubbo.apache.org/zh-cn/docs/user/demos/generic-reference.html)的文档,这个是可以实现的。

按照 `GenericService` 的定义
```java
public interface GenericService {

    /**
     * Generic invocation
     *
     * @param method         Method name, e.g. findPerson. If there are overridden methods, parameter info is
     *                       required, e.g. findPerson(java.lang.String)
     * @param parameterTypes Parameter types
     * @param args           Arguments
     * @return invocation return value
     * @throws Throwable potential exception thrown from the invocation
     */
    Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;

}
```
我需要知道 `方法名`, `方法的参数类型列表`, `实参列表`。
目前的假设条件(实际上满足,但我不想依赖这些条件)是:我没有 Dubbo Provider 的接口定义,就是我不知道 `Object $invoke(String method, String[] parameterTypes, Object[] args) ` 里面的 `method` 和 `parameterTypes`。我可以获得 `ZK` 地址,及也知道 Provider 的地址,随即也可以知道 `method` 信息, 就是不知道 `parameterTypes` 了。

## 现状

可以通过 Telnet 命令的  `ls -l XxxService` 知道 `parameterTypes` 的信息

## 期望
我这个工具是个后端服务,如果使用 `Telnet` 会比较麻烦,所以期望有没有提供直接通过 Provider 的地址和端口号,发送个内置的 GenericService 服务
如有个:
`org.apache.dubbo.rpc.dubbo.telnet.ListTelnetService` 的服务
可以通过`.$invoke("lsDetail", new String[]{"java.lang.String"}, new Object[]{"XxxService"} )`,获得类似于 `ls -l XxxService` 的结果。
或者其他的比创建个Telnet 连接 再发送指令更简单些的方式。


[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] xcorpio commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "xcorpio (GitHub)" <gi...@apache.org>.
只能 telnet 了吗 🤔

[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] gudegg commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "gudegg (GitHub)" <gi...@apache.org>.
> > > 不知道我是否理解你的意思了。
> > > 因为你说你有 ReferenceConfig ,所以我觉得可以通过反射来获取到你想调用方法的参数类型。
> > > ```
> > >  Method[] methods = ReferenceConfig.getInterfaceClass().getMethods();
> > >         for (Method method : methods) {
> > >             Class<?>[] parameter = method.getParameterTypes();
> > >         }
> > > ```
> > 
> > 
> > 没有,这个是通过泛型引用创建的,里面只有 `$invoke` 这个方法
> > <img alt="2019-01-07 7 40 37" width="987" src="https://user-images.githubusercontent.com/4575409/50766444-325ed600-12b4-11e9-98db-623d1d8bd429.png">
> 
> 没使用过泛化调用,但是我看了一下文档
> 
> ```
> ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); 
> // 弱类型接口名
> reference.setInterface("com.xxx.XxxService");  
> reference.setVersion("1.0.0");
> // 声明为泛化接口 
> reference.setGeneric(true);  
> ```
> 你已经获取到了需要调用的接口类型 也就是 "com.xxx.XxxService”, 反射它就好了。

泛化调用端不一定`com.xxx.XxxService`接口,反射是不可靠的。像一般dubbo泛化用于网关建设,是不存在当前接口架包的

[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] gudegg commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "gudegg (GitHub)" <gi...@apache.org>.
> > > 不知道我是否理解你的意思了。
> > > 因为你说你有 ReferenceConfig ,所以我觉得可以通过反射来获取到你想调用方法的参数类型。
> > > ```
> > >  Method[] methods = ReferenceConfig.getInterfaceClass().getMethods();
> > >         for (Method method : methods) {
> > >             Class<?>[] parameter = method.getParameterTypes();
> > >         }
> > > ```
> > 
> > 
> > 没有,这个是通过泛型引用创建的,里面只有 `$invoke` 这个方法
> > <img alt="2019-01-07 7 40 37" width="987" src="https://user-images.githubusercontent.com/4575409/50766444-325ed600-12b4-11e9-98db-623d1d8bd429.png">
> 
> 没使用过泛化调用,但是我看了一下文档
> 
> ```
> ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); 
> // 弱类型接口名
> reference.setInterface("com.xxx.XxxService");  
> reference.setVersion("1.0.0");
> // 声明为泛化接口 
> reference.setGeneric(true);  
> ```
> 你已经获取到了需要调用的接口类型 也就是 "com.xxx.XxxService”, 反射它就好了。

泛化调用端不一定有`com.xxx.XxxService`接口,反射是不可靠的。像一般dubbo泛化用于网关建设,是不存在当前接口架包的

[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] LiZhenNet commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "LiZhenNet (GitHub)" <gi...@apache.org>.
不知道我是否理解你的意思了。

因为你说你有 ReferenceConfig ,所以我觉得可以通过反射来获取到你想调用方法的参数类型。

`
 Method[] methods = ReferenceConfig.getInterfaceClass().getMethods();
        for (Method method : methods) {
            Class<?>[] parameter = method.getParameterTypes();
        }
`



[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] xcorpio commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "xcorpio (GitHub)" <gi...@apache.org>.
> 不知道我是否理解你的意思了。
> 
> 因为你说你有 ReferenceConfig ,所以我觉得可以通过反射来获取到你想调用方法的参数类型。
> 
> ```
>  Method[] methods = ReferenceConfig.getInterfaceClass().getMethods();
>         for (Method method : methods) {
>             Class<?>[] parameter = method.getParameterTypes();
>         }
> ```

没有,这个是通过泛型引用创建的,里面只有 `$invoke` 这个方法
<img width="987" alt="2019-01-07 7 40 37" src="https://user-images.githubusercontent.com/4575409/50766444-325ed600-12b4-11e9-98db-623d1d8bd429.png">


[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] xcorpio closed issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "xcorpio (GitHub)" <gi...@apache.org>.
[ issue closed by xcorpio ]

[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org


[GitHub] [incubator-dubbo] zonghaishang commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "zonghaishang (GitHub)" <gi...@apache.org>.
> @zonghaishang 的答案:
> 
> > @xcorpio telnet调用,代码可以开一个tcp长连接,按照dubbo提供的调用命令,直接写socket数据和读取就可以了
> > 如果你熟悉dubbo框架代码,请阅读:org.apache.dubbo.rpc.protocol.dubbo.telnet.InvokeTelnetHandler
> > 如果不熟悉,请使用sudo tcpdump -i any -A dst port 20880 抓包看返回数据
> 
> 我有个疑问,telent 好像判断了是否是clientside
> 
> ```java
> private static boolean isClientSide(Channel channel) {
>         InetSocketAddress address = channel.getRemoteAddress();  //1
>         URL url = channel.getUrl();
>         return url.getPort() == address.getPort() &&
>                 NetUtils.filterLocalHost(url.getIp())
>                         .equals(NetUtils.filterLocalHost(address.getAddress().getHostAddress())); //2
>     }
> ```
> 
> 在 1 这个点channel.getRemoteAddress(); 是获取调用方的地址吧。
> 在 2 的时候会判断调用方ip 跟本机是否一致

在consumer端时 channel.getRemoteAddress();获取的是provider端的地址
在provider端时,这个拿到的是consumer端地址

telent只能连接到provider方,可以理解为dubbo服务提供方。

[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] LiZhenNet commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "LiZhenNet (GitHub)" <gi...@apache.org>.
> > 不知道我是否理解你的意思了。
> > 因为你说你有 ReferenceConfig ,所以我觉得可以通过反射来获取到你想调用方法的参数类型。
> > ```
> >  Method[] methods = ReferenceConfig.getInterfaceClass().getMethods();
> >         for (Method method : methods) {
> >             Class<?>[] parameter = method.getParameterTypes();
> >         }
> > ```
> 
> 没有,这个是通过泛型引用创建的,里面只有 `$invoke` 这个方法
> <img alt="2019-01-07 7 40 37" width="987" src="https://user-images.githubusercontent.com/4575409/50766444-325ed600-12b4-11e9-98db-623d1d8bd429.png">

没使用过泛化调用,但是我看了一下文档
 ```
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); 
// 弱类型接口名
reference.setInterface("com.xxx.XxxService");  
reference.setVersion("1.0.0");
// 声明为泛化接口 
reference.setGeneric(true);  
```
你已经获取到了需要调用的接口类型 也就是 "com.xxx.XxxService”, 反射它就好了。


[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] LiZhenNet commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "LiZhenNet (GitHub)" <gi...@apache.org>.
@zonghaishang  的答案:
> @xcorpio telnet调用,代码可以开一个tcp长连接,按照dubbo提供的调用命令,直接写socket数据和读取就可以了
> 
> 如果你熟悉dubbo框架代码,请阅读:org.apache.dubbo.rpc.protocol.dubbo.telnet.InvokeTelnetHandler
> 
> 如果不熟悉,请使用sudo tcpdump -i any -A dst port 20880 抓包看返回数据

我有个疑问,telent 好像判断了是否是clientside

```java
private static boolean isClientSide(Channel channel) {
        InetSocketAddress address = channel.getRemoteAddress();  //1
        URL url = channel.getUrl();
        return url.getPort() == address.getPort() &&
                NetUtils.filterLocalHost(url.getIp())
                        .equals(NetUtils.filterLocalHost(address.getAddress().getHostAddress())); //2
    }

```
在 1 这个点channel.getRemoteAddress(); 是获取调用方的地址吧。
在 2 的时候会判断调用方ip 跟本机是否一致





[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org

[GitHub] [incubator-dubbo] LiZhenNet commented on issue #3161: Telnet 提供命令能否通过代码或泛化调用直接调用而不必通过 Telnet 协议

Posted by "LiZhenNet (GitHub)" <gi...@apache.org>.
不知道我是否理解你的意思了。

因为你说你有 ReferenceConfig ,所以我觉得可以通过反射来获取到你想调用方法的参数类型。

```
 Method[] methods = ReferenceConfig.getInterfaceClass().getMethods();
        for (Method method : methods) {
            Class<?>[] parameter = method.getParameterTypes();
        }
```



[ Full content available at: https://github.com/apache/incubator-dubbo/issues/3161 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org