2020년 Rust로 2진 gRPC 서버 클라이언트 구축 - 2부

In the previous post, we covered the scope of the project and we wrote the CLI frontend using StructOpt which we'll later use to package the implementation of our server and client.

It is recommended that you follow in order since each post builds off the progress of the previous post.

This is the second post of a 4 part series. If you would like to view this post in a single page, you can follow along on my blog.


프로토콜 버퍼



프로토콜 버퍼는 무엇입니까?


Protocol Buffers(protobufs)는 데이터 모델을 정의하는 방법으로 데이터의 구조를 정의하고 프로그램이 언어에 독립된 방식으로 데이터와 상호작용하는 방법을 정의한다.
이것은 프로토콜 형식으로 데이터를 작성하여 선택한 지원 언어로 컴파일하는 것입니다gRPC.
컴파일된 결과는 많은 샘플 코드를 생성했다.
언어의 원생 데이터 형식에만 같은 모양과 명칭이 정해진 데이터 구조가 있는 것이 아닙니다.그러나 이러한 생성된 데이터 구조를 보내거나 수신하는 클라이언트나 서버를 위해 gRPC 네트워크 코드를 생성합니다.
특히 서버와 클라이언트는 서로 다른 언어로 실현할 수 있고 문제가 없는 상황에서 상호작용할 수 있다.그러나 이 예에 대해 우리는 계속 완전히 녹 속에서 일할 것이다

protobuf는 코드 라이브러리의 어느 곳에 살아야 합니까?


프로토타입으로 뛰어들기 전에 파일 자체를 어디에 저장하는지 언급하고 싶습니다.
$ tree
.
├── Cargo.lock
├── Cargo.toml
├── proto
│ └── cli.proto
└── src
    └── main.rs
나는 프로토콜을 proto 이라는 디렉터리에 저장하는 것을 좋아한다. 보통 Cargo.toml 과 같은 단계에 있기 때문이다. 왜냐하면 스크립트 구축은 프로토콜의 경로를 인용하여 컴파일해야 한다는 것을 곧 볼 수 있기 때문이다.파일 이름 자체는 임의적naming things is hard이므로 의미 있는 이름으로 미래의 자신을 지원할 수 있도록 최선을 다해 주십시오.

예제 protobuf


cli。원형


syntax = "proto3";

package remotecli;

// Command input
message CommandInput {
 string command = 1;
 repeated string args = 2;
}

// Command output
message CommandOutput {
 string output = 1;
}

// Service definition
service RemoteCLI {
 rpc Shell(CommandInput) returns (CommandOutput);
}
우리는 우선 우리가 사용하고 있는 문법의 특정 버전을 성명한다.proto3 .
우리는 가방 이름을 제공해야 한다.
proto3 docs는 선택할 수 있음을 표시하지만, 프로토콜 녹 코드 생성기 Prost 는 모듈 이름 공간과 이름 결과 파일에 정의를 요구합니다.
두 가지 데이터 구조를 정의했는데 이를 messages라고 부른다.
필드의 순서는 번호입니다. gRPC 통신을 위해 필드를 서열화/반서열화할 때 필드의 순서는 유선 프로토콜의 필드를 식별하는 데 매우 중요합니다.
메시지의 숫자는 유일해야 하며, 가장 좋은 방법은 사용할 때 숫자를 변경하지 않는 것이다.
자세한 내용은 필드 번호에 대한 자세한 내용in the docs을 참조하십시오.CommandInput 메시지에는 2개의 string 필드가 있습니다. 하나는 단수이고 다른 하나는 repeated 필드입니다.
주 실행 파일, 우리는 command 사용자가 입력한 첫 번째 글자라고 부른다.
나머지 사용자 입력은 args 에서 유지됩니다.
이 분리는 Bash와 같은 명령 해석기에 명령을 정의하는 방식에 구조를 제공하기 위한 것이다.CommandOutput 메시지는 그렇게 많은 구조를 필요로 하지 않는다.명령을 실행하면 표준 출력은 하나의 텍스트 블록으로 되돌아옵니다.
마지막으로 우리는 단일 단점RemoteCLI을 가진 서비스Shell를 정의했다.Shell 획득CommandInput 및 복귀CommandOutput.

Tonic으로 protobuf를 컴파일합니다.



이제 프로토타입이 생겼습니다. 생성된 코드를 사용해야 할 때, 우리는 어떻게 Rust 프로그램에서 그것을 사용합니까?
좋습니다. 프로토타입을 Rust로 컴파일하기 위해 먼저 구축을 설정해야 합니다.
우리가 이 점을 실현하는 방법은 build script (Rust로 작성한 서프라이즈! 그러나 이것은 컴파일의 나머지 부분이 발생하기 전에 컴파일하고 실행하는 것이다.
프로젝트 루트 디렉터리에 build.rs 라는 파일이 있으면 Cargo는 구축 스크립트를 실행합니다.
$ tree
.
├── build.rs
├── Cargo.toml
├── proto
│ └── cli.proto
└── src
    └── main.rs

건축하다루피


fn main() {
   tonic_build::compile_protos("proto/cli.proto").unwrap();
}
구축 스크립트는 main() 함수가 있는 작은 Rust 프로그램일 뿐입니다.
우리는 현재 tonic_build를 사용하여 우리의 원형을 Rust로 컴파일하고 있다.우리는 곧 더 많은 tonic를 보게 될 것이다. 이것은 우리 gRPC 여정의 나머지 부분이 될 것이다.
그러나 지금 우리는 이 판자 상자를 구축 의존항으로 우리의 Cargo.toml 에 추가하기만 하면 된다.

화물톰


[package]
name = "cli-grpc-tonic-blocking"
version = "0.1.0"
authors = ["T.J. Telan <[email protected]>"]
edition = "2018"

[dependencies]
# CLI
structopt = "0.3"

[build-dependencies]
# protobuf->Rust compiler
tonic-build = "0.3.0"
구축 의존항은 자신의 부분[build-dependencies]에 열거되어 있다.만약 모르신다면, 구축 스크립트는 이 절에 열거된 판자 상자만 사용할 수 있고, 반대로도 사용할 수 있습니다.target 디렉터리에서 생성된 녹 코드를 볼 수 있습니다.
스크립트 출력을 생성하기 때문에, 여러 개의 디렉터리에 패키지 이름과 추가로 생성된 문자가 포함됩니다.따라서 여러 개의 디렉터리를 보아야 할 수도 있습니다.
$ tree target/debug/build/cli-grpc-tonic-blocking-aa0556a3d0cd89ff/
target/debug/build/cli-grpc-tonic-blocking-aa0556a3d0cd89ff/
├── invoked.timestamp
├── out
│ └── remotecli.rs
├── output
├── root-output
└── stderr
나는 코드를 생성하는 내용을 뒤에 남겨 둘 것이다. 왜냐하면 그 중에는 많은 내용이 있기 때문이다. 관련 정보는proto에서 오거나 서버와 클라이언트 구현에서 소개될 것이다.
이 코드는 한 번만 생성됩니다.또는 cargo build를 변경하지 않는 한따라서 프로토콜을 변경하고 코드를 다시 생성하려면 build.rs 를 사용하여 코드를 강제로 다시 생성할 수 있습니다.
$ touch build.rs
$ cargo build

We just covered the creation of our data schema in the Protocol Buffer format and using Tonic to compile the protobufs into Rust code with Rust build scripts.

In the next post we'll cover using our generated Rust code, the implementation of the gRPC server, and plugging in the code into our CLI frontend.

I hope you'll follow along!

좋은 웹페이지 즐겨찾기