작성중입니다.

마지막 수정일 : 2023-07-26

gRPC와 gRPC-Web 소개

gRPC란?

gRPC는 구글에서 개발한 고성능, 고신뢰성의 오픈소스 RPC(Remote Procedure Call) 프레임워크이다.
기본적으로 Protocol Buffers (protobuf)를 통해 데이터를 직렬화하는데, 이는 효율적인 데이터 직렬화 방법으로 알려져 있다.
또한, gRPC는 HTTP/2 프로토콜 위에서 작동하여 쌍방향 스트리밍과 플로우 컨트롤 등 다양한 기능을 제공을 해준다.

gRPC-Web이란?

gRPC-Web은 웹 클라이언트에서 gRPC 서비스를 직접 호출할 수 있게 해주는 JavaScript 클라이언트 라이브러리이다.
gRPC-Web을 이용하면 브라우저에서 서버로 바로 gRPC 요청을 보낼 수 있으며,
이는 웹 개발에서의 통신을 단순화하고, 서버 리소스를 효율적으로 활용하는 데 도움을 준다.

Protocol Buffers와 protoc

Protocol Buffers란?

Protocol Buffers (protobuf)는 구글이 개발한 데이터 직렬화 프로토콜로,
XML이나 JSON보다 훨씬 작고 빠르며 간단합니다. protobuf를 사용하면 데이터 구조를 .proto 파일에 정의하고,
해당 파일을 사용해 다양한 언어로 소스 코드를 생성할 수 있다.

protoc란?

protoc는 Protocol Buffers 컴파일러로, .proto 파일에서 소스 코드를 생성하는 데 사용된다.
이 컴파일러를 사용하면 개발자는 필요한 언어로 gRPC 클라이언트와 서버 스텁을 생성할 수 있습니다.

proto 문법 및 작성 방법

https://protobuf.dev/programming-guides/proto3/
proto 파일은 다음과 같은 구조로 이루어져 있다.
많은 예시들이 전부 hellowworld, greeter만 예시하고 있는게 불만이었다.
그래서 다른 예시를 작성해보았다.

syntax = "proto3";

// 해당 파일이 속한 패키지를 지정한다.
// 언어에 따라 다르게 생성된다.
// java : package
// c# : csharp_namespace
// js : package
// python : package
// Dart : package
option csharp_namespace = "InspectGrpcService";

option java_package = "com.inspect";
option java_multiple_files = true;
option java_outer_classname = "InspectProto";

package inspect;

// 해당 파일에서 사용할 수 있는 다른 proto 파일을 import 한다.
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/empty.proto";

service Inspecter {
  rpc GetPart (PartRequest) returns (PartReply);
  rpc UpdateInspect (InspectRequest) returns (InspectReply);
  rpc GetInspect (InspectListRequest) returns (InspectListReply);
}

message GrpcDecimal {
    int64 units = 1;
    sfixed32 nanos = 2;
}

message PartRequest {
  string partCodeX = 1;
}

message PartReply {
  string partName = 1;
  string partSpec = 2;
}

message InspectRequest {
  string barCode = 1;
 google.protobuf.Timestamp workDate = 2;
  google.protobuf.Timestamp scanTime = 3;
}
message InspectReply {
  string message = 1;
}

message InspectListRequest {
  google.protobuf.Timestamp inspectDate = 1;
}

message InspectListReply {
  string inspectJson = 1;
}

용어 정리

RPC(Remote Procedure Call)

RPC는 원격 프로시저 호출을 의미하며,

  1. 클라이언트가 서버에게 요청을 보낸다.
  2. 서버는 요청을 처리하고, 결과를 클라이언트에게 반환한다.
  3. 클라이언트는 결과를 받아서 처리한다.

gRPC 장점

gRPC는 구글에서 개발한 고성능, 고신뢰성의 오픈소스 RPC 프레임워크이다.

  1. gRPC는 HTTP/2 프로토콜 위에서 작동한다.
  2. HTTP/2는 기존 HTTP/1.1보다 효율적인 데이터 전송을 지원한다.
  3. HTTP/2는 다중화, 헤더 압축, 서버 푸시 등 다양한 기능을 제공한다.
  4. gRPC는 Protocol Buffers를 통해 데이터를 직렬화한다.
  5. Protocol Buffers는 XML이나 JSON보다 훨씬 작고 빠르며 간단하다.
  6. gRPC는 쌍방향 스트리밍과 플로우 컨트롤 등 다양한 기능을 제공한다.
  7. gRPC는 다양한 언어를 지원한다.

Protocol Buffers

Protocol Buffers는 구글에서 개발한 데이터 직렬화 프로토콜이다.

  1. Protocol Buffers는 XML이나 JSON보다 훨씬 작고 빠르며 간단하다.
  2. Protocol Buffers는 데이터 구조를 .proto 파일에 정의하고, 해당 파일을 사용해 다양한 언어로 소스 코드를 생성할 수 있다.
  3. Protocol Buffers는 데이터를 직렬화하는데 사용된다.

Stub

Stub은 클라이언트에서 서버로 요청을 보내는 데 사용되는 코드이다.
gRPC에서는 클라이언트에서 서버로 요청을 보내는 데 사용되는 코드를 Stub이라고 한다.

  1. gRPC는 Protocol Buffers를 통해 Stub을 생성한다.
  2. Stub은 클라이언트에서 서버로 요청을 보내는 데 사용되는 코드이다.
  3. 언어별 Stub은 상이하다.

gRPC 작업 순서

  1. proto 파일 작성 : 필요한 서비스와 메시지 타입을 정의한다.
  2. protoc를 이용한 소스 코드 생성: .proto 파일에서 개발에 필요한 언어의 소스 코드를 생성한다.
  3. 생성된 소스 코드를 이용해 gRPC 클라이언트와 서버를 개발을 하고, 서버를 실행합니다.
  4. 서버를 시작하고, 클라이언트에서 서버의 gRPC 메소드를 호출한다.
    • 언어별 gRPC 클라이언트와 서버를 개발하는 방법은 다음 링크를 참고하자.

각 언어별 gRPC-Web 지원 현황

gRPC-Web은 현재 지원하는 언어가 제한적이다.

JavaScript(TypeScript)
Flutter(Dart)
Go
Java, Kotlin
C#, C++, Python
Objective-C, Swift
그외 PHP, Ruby, Rust

gRPC-Web을 사용하기 위한 준비물

  1. protoc 컴파일러 다운로드
    https://github.com/protocolbuffers/protobuf

    다운을 받고 환경 변수도 등록해주자.

  2. gRPC-Web protoc 플러그인 다운로드
    https://github.com/grpc/grpc-web#code-generator-plugin

    https://github.com/grpc/grpc-web/releases
    여기서 Plugin을 다운받아서 protoc의 위치에 받는다.
    ** 귀찮다면 컴파일러 옆에 같이두자.

protoc 컴파일러 다운로드

Image1

나는 Windows 환경이기 때문에
protoc-gen-grpc-web-1.4.2-windows-x86_64.exe 를 다운받았다.

안보인다고?
ShowAll눌러보자 Show All 버튼을 눌러보자. 좀…

gRPC-Web 사용하기

Version 확인

protoc --version

//결과
libprotoc 23.3

Proto 파일 작성

Proto 파일은 문법설명 및 작성방법을 참고하자.

protoc 컴파일러를 이용한 소스 코드 생성

(중요)javascript Stub 생성하기전에 알아야할 것들

JavaScript와 관련된 gRPC-Web stub를 생성하려면 protoc-gen-grpc-web 플러그인이 필요합니다.

  • 브라우저에서는 require, import 형태는 사용할 수 없다.
  • 또한 javascript의 Stub은 2개를 생성해야한다.
  • 하나는 js_out, 하나는 grpc-web_out 이다.

js_out

‘js_out’ : 해당 옵션은 Protocol Buffers (protobuf)의 메시지와 서비스를 정의하는
‘.proto’ 파일을 기반으로 일반적인 JavaScript 클라이언트 코드를 생성한다.
이 코드는 주로 protobuf 메시지의 시리얼라이징 및 디시리얼라이징
(즉, JavaScript 객체와 바이너리 데이터 간의 변환)을 담당하는 코드다.

예를 들어, .proto 파일에 ‘message PartRequest {…}’ 라는
메시지가 정의되어 있다면, js_out으로 생성된 JavaScript 코드에서는
PartRequest라는 클래스를 제공하며, 이를 사용하여 PartRequest 메시지를 생성하고,
이를 바이너리 데이터로 시리얼라이징하거나,
반대로 바이너리 데이터를 PartRequest 객체로 디시리얼라이징할 수 있다.

grpc-web_out

‘grpc-web_out’ : 이 옵션은 ‘.proto’ 파일의 서비스 정의를 기반으로
gRPC-Web 클라이언트 스텁을 생성한다. 스텁은 gRPC 서비스 메서드를 직접 호출하는데 사용되며,
네트워크 통신과 관련된 모든 로직을 ‘캡슐화’한다.

예를 들어, .proto 파일에 ‘service Inspecter {…}’ 라는 서비스가 정의되어 있다면,
grpc-web_out으로 생성된 JavaScript 코드에서는 InspecterClient라는 클래스를 제공하며,
이를 사용하여 Inspecter 서비스의 메서드를 원격으로 호출할 수 있다. 스텁은 이러한
원격 호출을 위해 필요한 모든 네트워크 통신을 처리하며, 요청을 전송하고 응답을 받는 등의 역할을 한다.

js_out + grpc-web_out

결국, js_out은 protobuf 메시지를 다루는 데 필요한 코드를,
(js_out 은 Protocal Buffers를 사용하는데 필요한 코드)
grpc-web_out은 gRPC 서비스를 호출하는 데 필요한 코드를 각각 생성한다.
(grpc-web_out 은 gRPC 메소드를 호출하는데 필요한 코드)
그래서 보통 gRPC-Web 클라이언트를 작성할 때에는 이 두 종류의 코드를 모두 사용하게 된다.

JavaScript Stub 생성하기

그래서 다음과 같이 사용한다.

// 프로토파일 위치에서 CMD키자. 
//proto 파일이 있는 위치를 지정한다.
protoc --proto_path=C:\grpc-web-repo inspect.proto
//js_out 
--js_out=import_style=commonjs,mode=grpcwebtext:C:\Desktop\grpc-web-rep\js_out
//grpc-web_out
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:C:\Desktop\grpc-web-repo\grpc-web_out

현재위치인 경우 복붙.

protoc --proto_path=. inspect.proto --js_out=import_style=commonjs,mode=grpcwebtext:.\js_out --grpc-web_out=import_style=commonjs,mode=grpcwebtext:.\grpc-web_out
mode=grpcwebtext:. // Content-type : application/grpc-web-text 형태
// base64로 인코딩되고 서버 스트리밍호출도 지원
mode=grpcweb:. // Content-type : application/grpc-web+proto 형태
// protobuf 형태인데 unary만 지원중

이렇게 하면 오류없이 완료된다.

//jsout 폴더에 inspect_pb.js, inspect_grpc_web_pb.js 파일이 생성된다.

Closure Stub 생성하기

Closure Import Style은 Closure Library를 사용하는 경우에 사용한다.
import_style=closure를 사용하면 Closure Library에서 제공하는 goog.require()를 사용하여 import한다.

// 프로토파일 위치에서 CMD키자.
// . 의 위치를 수정하세요. 
protoc -I=. inspect.proto
--js_out=import_style=closure,mode=grpcwebtext:./js_out
--grpc-web_out=import_style=closure,mode=grpcwebtext:./grpc-web_out 

Stub 사용하기

JavaScript Stub 사용하기

To Be Continue… - Next Writing 2023-07-28

// index.html
<script src="https://cdn.jsdelivr.net/npm/google-protobuf@3.21.2/google-protobuf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/grpc-web@1.4.2/index.min.js"></script>
<script src="inspect_grpc_web_pb.js"></script>

// index.js
const { InspecterClient } = require('./inspect_grpc_web_pb.js');

const client = new InspecterClient('http://localhost:8080');

const request = new PartRequest();
request.setPartCodeX('1234567890');

client.getPart(request, {}, (err, response) => {
  if (err) {
    console.log(err);
  } else {
    console.log(response.toObject());
  }
});


이제 Web페이지로 이동해보자.

참고

오류

[오류]😬 –grpc-web_out: protoc-gen-grpc-web: Plugin failed with status code 1.

--grpc-web_out: protoc-gen-grpc-web: Plugin failed with status code 1.

해당오류는 다른오류가 있을 수는 있으나.

protoc-gen-grpc-web-1.3.1-windows-x86_64.exe
해당 파일명을
protoc-gen-grpc-web.exe  수정하자.

[오류]😬 –js_out :

Note: 만들고나니 내것이 아니었다.

Leave a comment