一. 将.proto 文件编译出java文件
1.下载对应系统的protoc;
【自用链接:https://pan.baidu.com/s/1yTwRi8CzvnjX9ICRExQpqQ 密码:mrow】
2.在proto.exe所在文件目录下打开命令行(shift+右键),执行:
protoc -I=E:\tmp --java_out=./ E:\tmp\send_mail.proto
【protoc.exe -I=.\读取目录 --java_out=./ 读取目录\send_mail.proto;】
a.加上 -I 是因为.proto文件不在当前目录下,出现问题:
File does not reside within any path specified using --proto_path (or -I). You must specify a --proto_path which encompasses this file. Note that the proto_path must be an exact prefix of the .proto file names -- protoc is too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it's harder than you think).;
b.用--java_out 是因为用 -java_out ,出现问题:
-j 命令不存在;
3.继续,执行: protoc.exe --plugin=protoc-gen-grpc-java=./protoc-gen-grpc-java-1.0.1-windows-x86_64.exe --grpc-java_out=./ send_mail.proto 生成Grpc.java文件;
4.将生成java文件复制到项目中;
二.附件
1.pom.xml
>添加依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.14</version>
</dependency>
<!-- 添加Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 添加grpc依赖 -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>1.1.2</version>
</dependency>
<!-- cassandra 相关 -->
<!-- thrift 连接方式 -->
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>cassandra-thrift</artifactId>
<version>2.1.17</version>
</dependency>
<!-- datastax 连接方式 -->
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>2.1.10.3</version>
<exclusions>
<!-- grpcServer启动需要高版本guava,此处先注释 -->
<!-- <exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion> -->
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
2.创建客户端、服务端
>客户端
public class GrpcClient{
/**
* GRPC客户端异步调用.
* @param req
* @param out
*/
public static void callGrpcClientAsyn(HttpServletRequest req, final PrintWriter out) {
try {
//异步调用
final ManagedChannel channel = NettyChannelBuilder.forAddress("127.0.0.1", PortManager.GRPC_SERVER_PORT.toInteger()).usePlaintext(true).build();
SendMailServiceFutureStub futureStub = SendMailServiceGrpc.newFutureStub(channel);
//服务端实现方式
String server = req.getParameter("server");
if (null == server) {
SendMailRequest futureParam = SendMailRequest.newBuilder().setRecipient("hxl@google.com").setTitle("异步grpc").setContent("SOA服务挂了").build();
ListenableFuture<SendMailResponse> futureResp = futureStub.sendMail(futureParam);
// System.out.println("futureSendMailResponse = " + futureResp.get().getMsg() + "\t" + futureResp.get().getCode());
out.println("-Server :[default null...]");
out.println("-Result :");
out.println("futureSendMailResponse = " + futureResp.get().getMsg() + "\t" + futureResp.get().getCode());
//close
channel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
return;
}
if (server.equals("ClientByStreaming")) {
//客户端流式rpc
SendMailServiceStub asyncStub = SendMailServiceGrpc.newStub(channel);
//client side
out.println("-Server :Client stream rpc.");
out.println("-Result :");
StreamObserver<Result> responseObserver = new StreamObserver<Result>() {
@Override
public void onNext(Result result) {
out.println("client stream--" + result.getString());
}
@Override
public void onError(Throwable t) {
}
@Override
public void onCompleted() {
//关闭channel
try {
channel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
StreamObserver<Person> clientStreamObserver = asyncStub.clientStreamHello(responseObserver);
clientStreamObserver.onNext(Person.newBuilder().setMyName("World").build());
clientStreamObserver.onNext(Person.newBuilder().setMyName("World2").build());
clientStreamObserver.onCompleted();
//由于是异步获得结果,所以sleep一秒
Thread.sleep(1000);
} else if (server.equals("BidirectionalStreaming")) {
//双向流式rpc
SendMailServiceStub asyncStub = SendMailServiceGrpc.newStub(channel);
Person person = Person.newBuilder().setMyName("World").build();
//bi stream
out.println("-Server :bidirectional stream rpc.");
out.println("-Result :");
StreamObserver<Result> responseObserver = new StreamObserver<Result>() {
@Override
public void onNext(Result result) {
out.println("bidirectional stream--"+result.getString());
}
@Override
public void onError(Throwable t) {
}
@Override
public void onCompleted() {
try {
channel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
StreamObserver<Person> biStreamObserver=asyncStub.biStreamHello(responseObserver);
biStreamObserver.onNext(Person.newBuilder().setMyName("World").build());
biStreamObserver.onNext(Person.newBuilder().setMyName("World2").build());
biStreamObserver.onCompleted();
//由于是异步获得结果,所以sleep一秒
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
/**
* GRPC客户端同步调用
* @param req
*/
public static void callGrpcClientSync(HttpServletRequest req, PrintWriter out){
final ManagedChannel channel = ManagedChannelBuilder.forAddress("127.0.0.1", PortManager.GRPC_SERVER_PORT.toInteger()).usePlaintext(true).build();
//同步调用(异步调用的话,就是:SendMailServiceGrpc.newFutureStub(channel))
SendMailServiceBlockingStub blockingStub = SendMailServiceGrpc.newBlockingStub(channel);
//服务端实现方式
String server = req.getParameter("server");
if(null == server){
try {
//设置请求参数
SendMailRequest blockingParam = SendMailRequest.newBuilder().setRecipient("admin@google.com").setTitle("同步grpc").setContent("SOA服务挂了").build();
SendMailResponse blockingResp = blockingStub.sendMail(blockingParam);
System.out.println("blockingSendMailResponse = " + blockingResp.getMsg() + "\t" + blockingResp.getCode());
out.println("blockingSendMailResponse = " + blockingResp.getMsg() + "\t" + blockingResp.getCode()+"<br>");
//close
channel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace(out);
}
return;
}
if (server.equals("SimpleRPC")) {
try {
//简单RPC
Person person = Person.newBuilder().setMyName("World").build();
//simple
out.println("-Server :simple rpc.");
out.println("-Result :"+blockingStub.simpleHello(person).getString());
channel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace(out);
}
} else if (server.equals("ServerByStreaming")) {
try {
//服务端流式RPC
Person person = Person.newBuilder().setMyName("World").build();
//server side
out.println("-Server :server stream rpc.");
out.println("-Result :");
//返回结果是Iterator
Iterator<Result> it = blockingStub.serverStreamHello(person);
while (it.hasNext()) {
out.print(it.next());
}
channel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace(out);
}
}
}
}
>服务端
public class GrpcServer implements ServletContextListener{
private static final Logger logger = Logger.getLogger("org.apache.log4j.ConsoleAppender");
static Server server = null;
@Override
public void contextInitialized(ServletContextEvent sce) {
try {
server = NettyServerBuilder.forPort(PortManager.GRPC_SERVER_PORT.toInteger())
.addService(new SendMailServiceImpl()).build();
server.start();
logger.info("grpc server startup at " + PortManager.GRPC_SERVER_PORT.toInteger());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
if (server != null) {
server.shutdown();
}
}
}
本文介绍了如何使用 protoc 编译 .proto 文件为 Java 代码,详细步骤包括下载 protoc 工具,解决.proto 文件路径问题,以及生成 Grpc.java 文件。同时提供了 pom.xml 的依赖添加方法,以及客户端和服务端的创建指南。
1674

被折叠的 条评论
为什么被折叠?



