[GRPC] GRPC Server(JAVA)와 Client(JAVA, NodeJS) 구축
이번 포스팅에서는 GRPC Server 및 Client(Stub)를 구축하려고 한다.
예제 코드를 확인하면 진행해보자.
https://github.com/alsdud154/grpc.git
먼저 GRPC Server(JAVA)를 만들자.
build.gradle이다.
작성 시점에서 grpcVresion 1.44.1이 maven repository 최신 버전이다.
Quick Start Example Project를 참고하여 만들었으니 설명은 공식 사이트를 참고하자.
plugins {
id 'application'
id 'com.google.protobuf' version '0.8.18'
id 'idea'
}
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
maven { // The google mirror is less flaky than mavenCentral()
url "https://maven-central.storage-download.googleapis.com/maven2/"
}
mavenCentral()
mavenLocal()
}
def grpcVersion = '1.44.1' // CURRENT_GRPC_VERSION
def protobufVersion = '3.19.2'
def protocVersion = protobufVersion
dependencies {
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
compileOnly "org.apache.tomcat:annotations-api:6.0.53"
// examples/advanced need this for JsonFormat
implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}"
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
testImplementation "io.grpc:grpc-testing:${grpcVersion}"
testImplementation "junit:junit:4.12"
testImplementation "org.mockito:mockito-core:3.4.0"
}
protobuf {
protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
}
generateProtoTasks {
all()*.plugins { grpc {} }
}
}
// Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code.
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
startScripts.enabled = false
그 다음으로 proto 파일을 생성하자. 단순히 성, 이름을 입력하면 서버에서 인사말을 응답해주는 예제이다.
syntax = "proto3";
// generated에 생성되는 패키지 경로
option java_package = "kr.co.velnova.grpc.helloworld";
// proto에 정의한 service, message 등을 개별 파일들로 만들어준다.
option java_multiple_files = true;
// client에서 호출할 패키지명
package hello;
service HelloService {
rpc HelloWorld(HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string first_name = 1;
string last_name = 2;
}
message HelloResponse {
string message = 1;
}
이제 proto를 컴파일하자.
아래와 같이 여러개 파일들로 생성되었다.
java_mulpile_files를 설정하지 않으면 1개의 파일로 만들어져 사용하기가 불편하다.
이제 generated된 자바 파일들을 사용하여 GRPC Server를 만들어보자.
먼저 HelloServiceImpl 구현체를 생성하자.
public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
@Override
public void helloWorld(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
String firstName = request.getFirstName();
String lastName = request.getLastName();
System.out.println(request);
HelloResponse helloResponse = HelloResponse.newBuilder()
.setMessage("hello! " + lastName + " " + firstName + "!")
.build();
responseObserver.onNext(helloResponse);
responseObserver.onCompleted();
}
}
그 다음으로 GrpcServer를 생성 후 구동해보자.
Main 함수를 실행하면 아래와 같이 구동되고 GRPC Client의 요청을 대기한다.
public class GrpcServer {
public static void main(String[] args) throws InterruptedException, IOException {
Server server = ServerBuilder
.forPort(8080)
.addService(new HelloServiceImpl()).build();
server.start();
server.awaitTermination();
}
}
이제 GRPC Client를 만들어보자.
오픈 소스로 GRPC를 만들거면 dependency(maven, npm 등)에 올려서 사용하면 되고 Private한 GRPC를 만들거면 이 예제와 같이 proto 파일을 공유 후 각 Client에서 해당 언어에 맞는 방식으로 활용하면 된다.
먼저 간단하게 JAVA Client를 만들어보겠다.
public class GrpcClient {
public static void main(String[] args) {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080)
.usePlaintext()
.build();
HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub(channel);
HelloResponse helloResponse = stub.helloWorld(HelloRequest.newBuilder()
.setFirstName("Velnova")
.setLastName("Jung")
.build());
System.out.println("response : " + helloResponse);
channel.shutdown();
}
}
main 함수를 실행해 테스트해보자.
Server
Client
이제 마지막으로 NodeJS에서 GRPC Client를 만들어보자.
npm i node-grpc-client
그 다음으로 GRPC Server를 만들 때 사용한 proto를 인터페이스로 사용하면 된다.
syntax = "proto3";
package hello;
service HelloService {
rpc HelloWorld(HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string first_name = 1;
string last_name = 2;
}
message HelloResponse {
string message = 1;
}
이제 index.js 파일에 GRPC Client를 만들고 서버를 호출해보자.
const path = require('path');
const PROTO_PATH = path.resolve(__dirname, 'proto/hello_service.proto');
const GRPCClient = require('node-grpc-client');
const myClient = new GRPCClient(PROTO_PATH, 'hello', 'HelloService', 'localhost:8080');
const dataToSend = {
first_name: 'Velnova',
last_name: 'Jung'
};
myClient.runService('HelloWorld', dataToSend, (err, res) => {
console.log('response: ', res);
}, {});
정상적으로 호출이 된다.