服务端业务逻辑代码
实现自己的业务逻辑类去继承grpc自动生成的类:
public class StudentServiceImpl extends StudentServiceGrpc.StudentServiceImplBase {
@Override
public void getRealNameByUsername(MyRequest request, StreamObserver<MyResponse> responseObserver) {
System.out.println("接受到客户端信息: " + request.getUsername());
responseObserver.onNext(MyResponse.newBuilder().setRealname("张三").build());
responseObserver.onCompleted();
}
}
可见返回的是void,所以需要返回的消息内容一定是由responseOberver来实现的。这单是跟thrift不同的地方。
onNext:把结果返回给客户端(考虑到会有stream情况)
onCompleted:告知客户端服务端,服务端已执行完毕
启动服务端
- 启动服务端
private void start() throws Exception{
this.server = ServerBuilder.forPort(8899).addService(new StudentServiceImpl()).build().start();
System.out.println("server started!");
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("关闭jvm");
GrpcServer.this.stop();
}));
System.out.println("执行到这里");
}
- 停止服务端
private void stop() {
if (null != this.server) {
this.server.shutdown();
}
}
- 让服务器等待(否则启动完就会退出)
private void awaitTermination() throws InterruptedException {
if (null != this.server){
this.server.awaitTermination();
}
}
- 执行
public static void main(String[] args) throws Exception{
GrpcServer server = new GrpcServer();
server.start();
server.awaitTermination();
}
启动客户端
public static void main(String[] args) {
ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 8899).usePlaintext(true).build();
StudentServiceGrpc.StudentServiceBlockingStub blockingStub = StudentServiceGrpc.newBlockingStub(managedChannel);
MyResponse myResponse = blockingStub.getRealNameByUsername(MyRequest.newBuilder().setUsername("张三").build());
System.out.println(myResponse.getRealname());
}
关键点
awaitTermination:等待服务器终止,可以传入时间参数来让服务器到达时间后terminate.
底层实现:
@Override
public void awaitTermination() throws InterruptedException {
synchronized (lock) {
while (!terminated) {
lock.wait();
}
}
}
Runtime:每一个java应用都会有一个单例Runtime对象,应用可以通过此对象获取应用环境的信息
addShutdownHook:回调钩子,虚拟机被关闭之前执行的方法
服务端与客户端建立的是一个tcp连接,是一个长连接,而不会像http一样客户端每次请求都需要建立一个新的连接,但是会通会过心跳检测这个连接是否有效。