由于ja-micro中,ServiceMethodHandler要求两个关键的参数必须是protobuf中Message的子类,这使得我在编写自己的handler时,必须先实现Protobuf的Message接口。然而,实现protobuf的接口,不需要自己 编写java代码,而是如同mybatis那样,定情一个配置文件,然后用工具生成出来的。当然,这个文件,必须得符合protoc的规范,其实,也很简单。就是告诉protobuf,需要生成什么样的参数类而已,其写法与JAVA语法相似。所以基本上一个c/c++、java之类的程序员,只要在网上随便找份关于protoc的教程,就能立即写出自己想要的参数类。例如,我想实现的功能是到一台Linux上面执行一条命令,将结果解析后返回出去。那么,我需要知道linux的ip地址、端口号、用户名、密码,这四个基本参数(具体执行的命令固化到代码中,所以不需要作为参数传递)。采集到数据后,我要返回的参数包含一个状态值,和一个结果字符串,那么,我的protoc文件内容如下:
syntax = "proto3";
package com.test.api;
option java_multiple_files = true;
option java_package = "com.test.api";
message BizSshRequest {
string ipaddr=1;
int32 port =2;
string username=3;
string password=4;
}
message BizResponse {
int32 status=1;
string Data=2;
}
syntax是标记使用的protoc协议版本,使用protoc3相对来说更容易上手。
option java_multiple_files = true; 这一行的意思是将protoc内容生成在多个文件中。
option java_package = "com.test.api"; 这一行很好理解了,生成的类在哪个包下面,java专用。
message就相当于class了。很明显在这里,我定义了两个类,其中BizRequest用于接收参数的类,BizResponse用于返回数据的类。事实上,它还可以支持更复杂的数据格式,具体的需要自己去搜索。
写完这个文件后,将其保存为一个扩展名为proto的文件。接下来就要编译这个文件了,将这个文件编译生成对应的java 类文件。编译工具下载地址:https://github.com/google/protobuf/releases/tag/v3.3.0,在新弹出的页面里面找到最下面的protoc-3.3.0-win32.zip,点击下载。下完后之后,将protoc.exe文件解压到JDK的bin目录下面即可。这样做的目的是为了直接利用环境变量中的jdk目录,无需再在path里面重写定义一个值。然后就可以在命令行里面,切换到protoc文件所在的目录,使用prococ命令编译proto文件。如下图示:
这样执行后,会在j第二个参数指定的工程中,生成相应的java文件:
这样就得到了我所期望的BizRequest和BizResponse两个用于传参数的类。它们都是GeneratedMessageV3的子类,也就是Message的子类,完全符合ServiceMethodHandler的泛型要求。这样,我要实现的handler就可以这样做出来了。
@RpcHandler("monitor.SshGetLinuxMemInfo")
public class SshGetLinuxMemInfo implements ServiceMethodHandler<BizSshRequest, BizResponse> {
@Override
public BizResponse handleRequest(BizSshRequest request,
OrangeContext otx) throws RpcCallException {
BizResponse.Builder build = BizResponse.newBuilder();
SshClient sshClient = new SshClient();
sshClient.setIpAddr(request.getIpaddr());
sshClient.setnPort(request.getPort());
sshClient.setUserName(request.getUsername());
sshClient.setPassWord(request.getPassword());
String cmd = "cat /proc/meminfo";
String strResult = "";
try {
sshClient.connect();
sshClient.login();
strResult = sshClient.executeCmd(cmd);
} catch (CommunicationException e) {
e.printStackTrace();
}finally{
if(null != sshClient ){
try {
sshClient.close();
} catch (CommunicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
build.setStatus(1);
build.setData(strResult);
BizResponse response = build.build();
return response;
}
定义好了Handler,再次启动JettyServiceBase中的main方法,就有服务供其它程序可以调用了。如何来测试这个服务呢?由于我用的是consul平台,所以先下载了一个consul程序,设置好启动用的参数,再下载一个micro程序,其实就是两个win32的可执行文件,当这两个程序运行后,再启动自己的工程,就能够测试编写的handler是否生效了:
其中一些细节与之前介绍的略有出入,因为我修改了一点ja-micro的源代码,使之更适合我的工程。这些下一节再介绍。工程中用到了consul、micro这两个工具,网上其实也有很多资料,有兴趣的可以在网上搜索一下。有时间我也另外写一点心得出来。