Swift에서 async/await를 사용하여 gRPC 서버 구축
개시하다
MacOS에서 Swift를 사용하여 gRPC 서버를 실행하고 Swift5를 사용합니다.5에서 가져온 async/await에 기술합니다.
ASync/await를 사용하려면 iOS 15와 MacOS Monteerey가 필요하지만, iOS 시뮬레이터를 사용하면 Big Sur도 ASync/await의 Swift 코드를 이동할 수 있다.
이번에 맥OS에서 이동하기 때문에 맥OS를 몬테리로 끌어올려야 한다.어쨌든 향상시키고 싶지 않은 사람은 Dcoker에서 리눅스 이미지를 사용해서 행동하거나 뒤의 디버깅을 기다려야 한다.
gRPC의 설치 사용grpc-swift.
async/await의 지원이 현재 Experimental이기 때문에 주의해야 합니다.앞으로 인터페이스 등은 파괴적인 변경이 있을 수 있다.
컨디션
protoc와grpc에 사용할 protoc 플러그인 준비
프로토 파일에서 코드를 생성하기 위해서는 명령
protoc
이 필요합니다.또한 스위프트용 Protocol Buffers 모델의 코드와 gRPC의 서버 클라이언트 코드를 생성하기 위해서는 각각의 플러그인이 필요하다.
이번
protoc
brew로 설치했어요.$ brew install protobuf
Swift용 플러그인의 두 가지는 자체적으로 구축하고 준비한 것입니다.본고에서 처음에 말한 바와 같이grpc-swift의 async/await 지원은 현재도 Experimental이며main 지점은 지원되지 않습니다.
따라서 전용 지점으로 전환한 후 구축합니다.
$ git clone https://github.com/grpc/grpc-swift.git
$ cd grpc-swift
$ git switch 1.4.1-async-await
$ make plugins
이로써 창고 경로에서 생성protoc-gen-swift
protoc-gen-grpc-swift
.(실제로 SwiftPM에서 작성된 파일만 복사
.build/release
합니다.)이 두 실행 가능한 파일의 경로를 통해
SwiftPM 프로젝트 제작
패키지 초기화
$ mkdir GrpcEcho
$ cd GrpcEcho
$ swift package init --type executable
Package.swift의 기술
이전과 마찬가지로 async/await 지원은 Experimental이기 때문에 전용 지점을 지정합니다.
또한 async/await를 사용하기 위해서plaforms에 지정해야 합니다
.macOS(.v12)
Package.swift// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "GrpcEcho",
platforms: [.macOS(.v12)],
dependencies: [
.package(url: "https://github.com/grpc/grpc-swift.git", .branch("1.4.1-async-await")),
],
targets: [
.executableTarget(
name: "GrpcEcho",
dependencies: [.product(name: "GRPC", package: "grpc-swift")]
),
]
)
.proto 파일 작성
연습 서버에 대한
.proto
파일을 설명합니다.이번에는 포장된 루트 목록에 적당히 놓을 것이다.
echo.proto
syntax = "proto3";
package echo;
service Echo {
rpc Hello(HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
.proto 파일 구성
protoc
를 사용하여 코드를 생성합니다.async/await를 지원하는 서버 코드를 생성하려면
ExperimentalAsyncServer
옵션을 사용해야 합니다.EventLoop의 일반 서버용 코드를 직접 사용할 필요가 없기 때문에 그쪽은 무효입니다.고객 코드가 이번에도 실현되지 않아서 무효입니다.각자의 목적에 따라 적절하게 설정하다.
옵션plugin.md에 기재되어 있습니다.
$ mkdir -p Sources/GrpcEcho/Gen
$ protoc echo.proto --swift_out=Sources/GrpcEcho/Gen --grpc-swift_out=Sources/GrpcEcho/Gen --grpc-swift_opt=Server=false,Client=false,ExperimentalAsyncServer=true
를 생성물echo.grpc.swift
과echo.pb.swift
로 출력Sources/GrpcEcho/Gen
.생성물은 일반적인 Swift 코드입니다.서버 코드 설명
각 Service는 Provider 클래스를 정의하고 서버에 클래스를 등록합니다.
이번에
Echo
서비스와 Hello
방법을 정의했고 이 인터페이스를 바탕으로 자동으로 생성된 프로토콜Echo_EchoAsyncProvider
에 대해 구체적인 실시 방안을 정의했다.main.swift
import GRPC
import NIO
class EchoProvider: Echo_EchoAsyncProvider {
func hello(request: Echo_HelloRequest, context: GRPCAsyncServerCallContext) async throws -> Echo_HelloResponse {
return Echo_HelloResponse.with {
$0.message = "Hello, \(request.name)"
}
}
}
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
defer {
try! group.syncShutdownGracefully()
}
let server = try Server.insecure(group: group)
.withServiceProviders([
EchoProvider(),
])
.bind(host: "localhost", port: 8080)
.wait()
print("started server: \(server.channel.localAddress!)")
try server.onClose.wait()
실행되면 서버에서 요청을 시작하고 기다립니다.동작 확인
방금 만든 서버에 적절한 gRPC 클라이언트 요청을 보냅니다.
이번에grpcurl을 사용했습니다.
$ brew install grpcurl
실제로 요구를 제기하려고 시도한다.$ grpcurl -plaintext -proto echo.proto -d '{"name": "Iceman"}' localhost:8080 echo.Echo.Hello
{
"message": "Hello, Iceman"
}
동작이 순조롭다.-plaintext
가 없으면 Unable to determine http version, closing
오류 로그를 뱉으면서 응답이 없음Failed to dial target host "localhost:8080": EOF
으로 답장하는 것을 주의하십시오.기본 설정에서 서버 로그는 허무하게 버려지기 때문에 적절한 설정이 필요합니다.
끝말
Swift를 사용하여 gRPC 서버를 이동할 수 있습니다.또한 Swift의 최신 기능인 async/await도 사용할 수 있다(이번 샘플 코드는 특별한 장점이 없다).
주의점은 스위프트에 대응하는 structured conceurncy라고 하지만 실제 상황은 스위프트 NIO를 기반으로 한 이벤트롭으로 움직인다는 점이다.
현재 EventLoop은 actor의 custom executor를 지원하지 않으며 이에 대해 특별한 협력이 없습니다.예를 들어, await의 위치에 따라 EventLoop의 바깥쪽도 처리됩니다.Async 컨텍스트에서 EventLoop에서 보호되는 리소스를 액세스할 때는 주의해야 합니다.
또 await 등 퓨처가 완성되는 타이밍에 본질적으로 필요 없는 스레드 스위치가 발생할 수 있다.기본적으로 문제가 없지만 연기에 불리하다.퍼포먼스가 엄격한 API에서는 사용하지 않는 것이 현명하다고 생각합니다.
이번 작업 코드는 여기 있습니다https://github.com/sidepelican/GrpcEcho
Reference
이 문제에 관하여(Swift에서 async/await를 사용하여 gRPC 서버 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/iceman/articles/3ff95611959c91텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)