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