Skip to content

Latest commit

 

History

History
279 lines (213 loc) · 10.9 KB

File metadata and controls

279 lines (213 loc) · 10.9 KB

GitHub

Core concepts, architecture and lifecycle | gRPC

Supported channels:

Awesome gRPC: A curated list of useful resources for gRPC

Showcase | gRPC

Channels

Custom Name Resolution | gRPC

Ordering

gRPC guarantees message ordering within an individual RPC call.

How does grpc guarantee the request (and response) order?

  • As far as I understand, we give no guarantees about the order in which messages will be delivered for separate calls, even on the same channel. Even if it did, the calls could be handled by different threads on the server, which could arbitrarily interleave and execute their handling code in any order.

  • If you need ordering you could use a grpc stream, which guarantees in order delivery of each message sent on the stream.

Sessions

gRPC is stateless. gRPC services are transient.

Bidirectional streaming

gRPC 只支持单向调用,不过 bidirectional streaming 可以作为双向调用的一种间接实现,例如:

service FullDuplex {
    rpc WaitRequests(stream ClientResponse) returns (stream ServerRequest);
}

虽然用这种方法实现反向调用有些 hacky,但这样做也有一个好处:方便追踪调用链。

gRPC-Web 目前尚不支持 bidirectional streaming。

protocol buffers - Protobuf RPC callbacks - Stack Overflow

  • Metadata

    • authorization

    Rust: tonic/examples/src/authentication/server.rs at master - hyperium/tonic

    #[derive(Clone)]
    pub struct AuthInterceptor {
        pub auth: Option<Arc<tonic::metadata::MetadataValue<tonic::metadata::Ascii>>>,
    }
    
    impl AuthInterceptor {
        pub fn new(auth: Option<&str>) -> Self {
            Self {
                auth: auth.map(|auth| auth.parse().unwrap()).map(Arc::new),
            }
        }
    }
    
    impl tonic::service::Interceptor for AuthInterceptor {
        fn call(&mut self, mut req: tonic::Request<()>) -> tonic::Result<tonic::Request<()>> {
            if let Some(auth) = &self.auth {
                req.metadata_mut()
                    .insert("authorization", auth.as_ref().clone());
            }
            Ok(req)
        }
    }
    
    client: MyServiceClient<
        tonic::service::interceptor::InterceptedService<
            tonic::transport::channel::Channel,
            AuthInterceptor,
        >,
    >,

Implementations

Supported languages | gRPC

  • C++
  • Rust (unofficial)
  • Go
  • .NET
  • JVM
    • Java
    • Kotlin
  • Python
  • Ruby
  • Web
    • JavaScript (gRPC-Web)
    • Node.js
  • PHP
  • Objective-C
  • Dart

Various gRPC benchmarks

.NET

Rust

Notes:

Build:

  • One crate

    [package]
    name = "plugin"
    version = "0.1.0"
    edition = "2021"
    
    [[bin]]
    name = "plugin-server"
    path = "src/server.rs"
    
    [[bin]]
    name = "plugin-client"
    path = "src/client.rs"
    
    [dependencies]
    prost = "0.12"
    tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
    tonic = "0.11"
    ...server_deps
    ...client_deps
    
    [build-dependencies]
    tonic-build = "0.11"
  • Three crates

    plugin:

    [package]
    name = "plugin"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    prost = "0.12"
    tonic = "0.11"
    
    [build-dependencies]
    tonic-build = "0.11"

    plugin-server:

    [package]
    name = "plugin-server"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    plugin = { path = "../plugin" }
    tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
    tonic = "0.11"
    ...server_deps

    plugin-client:

    [package]
    name = "plugin-client"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    plugin = { path = "../plugin" }
    tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
    tonic = "0.11"
    ...client_deps

Tools

GUI:

CLI: