<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Rust SDK Manual on Apache Dubbo</title><link>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/</link><description>Recent content in Rust SDK Manual on Apache Dubbo</description><generator>Hugo</generator><language>en</language><atom:link href="https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/index.xml" rel="self" type="application/rss+xml"/><item><title>Quick Start</title><link>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/quick-start/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/quick-start/</guid><description>&lt;p>View the complete &lt;a href="https://github.com/apache/dubbo-rust/tree/main/examples/greeter">example&lt;/a> here.&lt;/p>
&lt;h2 id="1-prerequisites">1 Prerequisites&lt;/h2>
&lt;ul>
&lt;li>Install the &lt;a href="https://rustup.rs/">Rust&lt;/a> development environment&lt;/li>
&lt;li>Install the &lt;a href="https://grpc.io/docs/protoc-installation/">protoc&lt;/a> tool&lt;/li>
&lt;/ul>
&lt;h2 id="2-define-dubbo-services-using-idl">2 Define Dubbo Services Using IDL&lt;/h2>
&lt;p>The Greeter service is defined as follows, including a Dubbo service with a Unary (request-response) model.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// ./proto/greeter.proto
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>syntax &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;proto3&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> java_multiple_files &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#cb4b16">true&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> org&lt;span style="color:#719e07">.&lt;/span>apache.dubbo.sample.tri;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// The request message containing the user&amp;#39;s name.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreeterRequest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> name &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// The response message containing the greetings
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreeterReply&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> &lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">service&lt;/span> Greeter{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// unary
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> &lt;span style="color:#719e07">rpc&lt;/span> greet(GreeterRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreeterReply);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="3-add-dubbo-rust-and-related-dependencies-to-the-project">3 Add Dubbo-rust and Related Dependencies to the Project&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-toml" data-lang="toml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"># ./Cargo.toml&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[package]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>name = &lt;span style="color:#2aa198">&amp;#34;example-greeter&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>version = &lt;span style="color:#2aa198">&amp;#34;0.1.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>edition = &lt;span style="color:#2aa198">&amp;#34;2021&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[[bin]]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>name = &lt;span style="color:#2aa198">&amp;#34;greeter-server&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>path = &lt;span style="color:#2aa198">&amp;#34;src/greeter/server.rs&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[[bin]]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>name = &lt;span style="color:#2aa198">&amp;#34;greeter-client&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>path = &lt;span style="color:#2aa198">&amp;#34;src/greeter/client.rs&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[dependencies]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>http = &lt;span style="color:#2aa198">&amp;#34;0.2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>http-body = &lt;span style="color:#2aa198">&amp;#34;0.4.4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>futures-util = {version = &lt;span style="color:#2aa198">&amp;#34;0.3&amp;#34;&lt;/span>, default-features = &lt;span style="color:#cb4b16">false&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tokio = { version = &lt;span style="color:#2aa198">&amp;#34;1.0&amp;#34;&lt;/span>, features = [ &lt;span style="color:#2aa198">&amp;#34;rt-multi-thread&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;time&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;fs&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;macros&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;net&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;signal&amp;#34;&lt;/span>] }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prost-derive = {version = &lt;span style="color:#2aa198">&amp;#34;0.10&amp;#34;&lt;/span>, optional = &lt;span style="color:#cb4b16">true&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prost = &lt;span style="color:#2aa198">&amp;#34;0.10.4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>async-trait = &lt;span style="color:#2aa198">&amp;#34;0.1.56&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tokio-stream = &lt;span style="color:#2aa198">&amp;#34;0.1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>dubbo = &lt;span style="color:#2aa198">&amp;#34;0.1.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>dubbo-config = &lt;span style="color:#2aa198">&amp;#34;0.1.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[build-dependencies]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>dubbo-build = &lt;span style="color:#2aa198">&amp;#34;0.1.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="4-configure-dubbo-build-to-compile-idl">4 Configure dubbo-build to Compile IDL&lt;/h2>
&lt;p>Create a &lt;code>build.rs&lt;/code> file in the project root directory (not /src) and add the following content:&lt;/p></description></item><item><title>Interoperability between Rust and Java</title><link>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/java-interoperability/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/java-interoperability/</guid><description>&lt;h2 id="1-prerequisites">1 Prerequisites&lt;/h2>
&lt;ul>
&lt;li>Install the &lt;a href="https://rustup.rs/">Rust&lt;/a> development environment&lt;/li>
&lt;li>Install the &lt;a href="https://grpc.io/docs/protoc-installation/">protoc&lt;/a> tool&lt;/li>
&lt;li>Install the Java development environment&lt;/li>
&lt;/ul>
&lt;h2 id="2-run-the-example-java-version-of-dubbo-provider">2 Run the Example Java Version of Dubbo Provider&lt;/h2>
&lt;p>The source code for the Java version of the Dubbo provider can be found at &lt;a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple">https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple&lt;/a>.&lt;/p>
&lt;p>Clone the source code, compile, and run the provider:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ &lt;span style="color:#586e75"># clone the source code&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ git clone https://github.com/apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ &lt;span style="color:#b58900">cd&lt;/span> dubbo-samples/dubbo-samples-triple/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ &lt;span style="color:#586e75"># build&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ mvn clean compile package -DskipTests
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ &lt;span style="color:#586e75"># run the provider&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ java -Dprovider.port&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">8888&lt;/span> -jar ./target/dubbo-samples-triple-1.0-SNAPSHOT.jar
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"># … omitted part of the logs&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Dubbo triple stub server started, &lt;span style="color:#268bd2">port&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">8888&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;a href="https://github.com/apache/dubbo-samples/blob/master/3-extensions/protocol/dubbo-samples-triple/src/main/proto/greeter.proto">Interface definition on the Java side&lt;/a>&lt;/p></description></item><item><title>Service Discovery</title><link>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/service-discovery/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/service-discovery/</guid><description>&lt;h2 id="introduction-to-dubbo-rust-service-discovery">Introduction to Dubbo Rust Service Discovery&lt;/h2>
&lt;p>Dubbo Rust provides a client-based service discovery mechanism that relies on third-party registry components to coordinate the service discovery process. Supported registries: Nacos, Zookeeper.&lt;/p>
&lt;p>The following is a basic working principle diagram of the Dubbo Rust service discovery mechanism:&lt;/p>
&lt;p>&lt;img alt="service-discovery" src="https://deploy-preview-3203--dubbo.netlify.app/imgs/rust/dubbo-rust-service-discovery.png">&lt;/p>
&lt;p>Service discovery involves three participant roles: provider, consumer, and registry. The Dubbo provider instance registers its URL with the registry, which is responsible for aggregating the data. The Dubbo consumer reads the address list from the registry and subscribes to changes. Whenever the address list changes, the registry notifies all subscribed consumer instances with the latest list.&lt;/p></description></item><item><title>Service Routing Rules</title><link>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/router-module/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/router-module/</guid><description>&lt;h2 id="conditional-routing">Conditional Routing&lt;/h2>
&lt;p>The usage pattern is similar to the &lt;a href="https://deploy-preview-3203--dubbo.netlify.app/en/overview/core-features/traffic/condition-rule/">Conditional Routing Documentation&lt;/a>, but the configuration format is slightly different. Below is an example of conditional routing rules.&lt;/p>
&lt;p>Based on the following example rule, all calls to the &lt;code>greet&lt;/code> method of the &lt;code>org.apache.dubbo.sample.tri.Greeter&lt;/code> service will be forwarded to a subset of addresses marked with &lt;code>port=8888&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">configVersion&lt;/span>: v1.0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">scope&lt;/span>: &lt;span style="color:#2aa198">&amp;#34;service&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">force&lt;/span>: &lt;span style="color:#cb4b16">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">enabled&lt;/span>: &lt;span style="color:#cb4b16">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">key&lt;/span>: &lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.sample.tri.Greeter&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">conditions&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - method=greet =&amp;gt; port=8888
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Note:&lt;br>
The Dubbo Rust currently does not distinguish at the &lt;strong>application level&lt;/strong>, and cannot differentiate the origin of the service.&lt;br>
Therefore, for tag routing and conditional routing, only one application-level configuration can be specified.&lt;br>
For application-level configuration, the default key is set to application, and this configuration will affect all services.&lt;br>
For example:&lt;/p></description></item><item><title>Communication using Unix Socket Connector</title><link>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/unix-transport/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/unix-transport/</guid><description>&lt;p>This article focuses on using the Dubbo Rust Triple protocol with Unix sockets. Please refer to the &lt;a href="../quick-start">Quick Start&lt;/a> for basic usage of Dubbo Rust, and you can see the &lt;a href="https://github.com/apache/dubbo-rust/tree/main/examples/greeter">complete example&lt;/a> here.&lt;/p>
&lt;h2 id="1-explanation-of-using-unix-socket-connector">1 Explanation of Using Unix Socket Connector&lt;/h2>
&lt;blockquote>
&lt;p>#[cfg(any(target_os = &amp;ldquo;macos&amp;rdquo;, target_os=&amp;ldquo;unix&amp;rdquo;))] The unix module will be compiled for use when the operating system meets the cfg configuration, otherwise it cannot be used.&lt;/p>
&lt;/blockquote>
&lt;h2 id="2-logic-for-using-unix-socket-connector-with-clientconnection">2 Logic for Using Unix Socket Connector with client/connection&lt;/h2>
&lt;h3 id="21-writing-the-client-side">2.1 Writing the Client Side&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-rust" data-lang="rust">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// examples/echo/src/echo/client.rs
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// Initialize Client using ClientBuilder
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#268bd2">let&lt;/span> builder &lt;span style="color:#719e07">=&lt;/span> ClientBuilder::new().with_connector(&lt;span style="color:#2aa198">&amp;#34;unix&amp;#34;&lt;/span>).with_host(&lt;span style="color:#2aa198">&amp;#34;unix://127.0.0.1:8888&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#719e07">mut&lt;/span> cli &lt;span style="color:#719e07">=&lt;/span> EchoClient::build(builder);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="22-writing-the-server-side">2.2 Writing the Server Side&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-rust" data-lang="rust">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// examples/echo/src/echo/server.rs
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// Initialize Server using serverbuilder
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#268bd2">let&lt;/span> builder &lt;span style="color:#719e07">=&lt;/span> ServerBuilder::new()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .with_listener(&lt;span style="color:#2aa198">&amp;#34;unix&amp;#34;&lt;/span>.to_string())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .with_service_names(vec![&lt;span style="color:#2aa198">&amp;#34;grpc.examples.echo.Echo&amp;#34;&lt;/span>.to_string()])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .with_addr(&lt;span style="color:#2aa198">&amp;#34;127.0.0.1:8888&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.build().serve().&lt;span style="color:#719e07">await&lt;/span>.unwrap();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="3-running-example">3 Running Example&lt;/h2>
&lt;ol>
&lt;li>Compile&lt;/li>
&lt;/ol>
&lt;p>Run &lt;code>cargo build&lt;/code> to compile the server and client.&lt;/p></description></item><item><title>Streaming Communication Model</title><link>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/streaming/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3203--dubbo.netlify.app/en/overview/mannual/rust-sdk/streaming/</guid><description>&lt;p>This article focuses on the Dubbo Rust Streaming communication pattern. Please refer to the &lt;a href="../quick-start">Quick Start&lt;/a> to understand the basic usage of Dubbo Rust and view the &lt;a href="https://github.com/apache/dubbo-rust/tree/main/examples/greeter">complete example&lt;/a> for this article.&lt;/p>
&lt;h2 id="1-adding-streaming-model-definitions-in-idl">1 Adding Streaming Model Definitions in IDL&lt;/h2>
&lt;p>The complete Greeter service definition is as follows, which includes a Unary, Client stream, Server stream, and Bidirectional stream model for Dubbo services.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// ./proto/greeter.proto
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>syntax &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;proto3&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> java_multiple_files &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#cb4b16">true&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> org&lt;span style="color:#719e07">.&lt;/span>apache.dubbo.sample.tri;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// The request message containing the user&amp;#39;s name.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreeterRequest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> name &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// The response message containing the greetings
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#268bd2">GreeterReply&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> &lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">service&lt;/span> Greeter{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// unary
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> &lt;span style="color:#719e07">rpc&lt;/span> greet(GreeterRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreeterReply);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// clientStream
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> &lt;span style="color:#719e07">rpc&lt;/span> greetClientStream(stream GreeterRequest) &lt;span style="color:#719e07">returns&lt;/span> (GreeterReply);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// serverStream
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> &lt;span style="color:#719e07">rpc&lt;/span> greetServerStream(GreeterRequest) &lt;span style="color:#719e07">returns&lt;/span> (stream GreeterReply);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// bi streaming
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> &lt;span style="color:#719e07">rpc&lt;/span> greetStream(stream GreeterRequest) &lt;span style="color:#719e07">returns&lt;/span> (stream GreeterReply);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="2-writing-logic-with-streaming-model-definitions">2 Writing Logic with Streaming Model Definitions&lt;/h2>
&lt;h3 id="21-writing-the-streaming-server">2.1 Writing the Streaming Server&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-rust" data-lang="rust">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// ./src/greeter/server.rs
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#719e07">pub&lt;/span> &lt;span style="color:#719e07">mod&lt;/span> protos {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> include!(concat!(env!(&lt;span style="color:#2aa198">&amp;#34;OUT_DIR&amp;#34;&lt;/span>), &lt;span style="color:#2aa198">&amp;#34;/org.apache.dubbo.sample.tri.rs&amp;#34;&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> futures_util::StreamExt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> protos::{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> greeter_server::{register_server, Greeter},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreeterReply, GreeterRequest,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>};
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> std::{io::ErrorKind, pin::Pin};
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> async_trait::async_trait;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> futures_util::Stream;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> tokio::sync::mpsc;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> tokio_stream::wrappers::ReceiverStream;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> dubbo_config::RootConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> dubbo::{codegen::&lt;span style="color:#719e07">*&lt;/span>, Dubbo};
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">type&lt;/span> &lt;span style="color:#268bd2">ResponseStream&lt;/span> &lt;span style="color:#719e07">=&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Pin&lt;span style="color:#719e07">&amp;lt;&lt;/span>&lt;span style="color:#b58900">Box&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>&lt;span style="color:#719e07">dyn&lt;/span> Stream&lt;span style="color:#719e07">&amp;lt;&lt;/span>Item &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#b58900">Result&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreeterReply, dubbo::status::Status&lt;span style="color:#719e07">&amp;gt;&amp;gt;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#b58900">Send&lt;/span>&lt;span style="color:#719e07">&amp;gt;&amp;gt;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">#[tokio::main]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">async&lt;/span> &lt;span style="color:#719e07">fn&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> register_server(GreeterServerImpl {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;greeter&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Dubbo::new().start().await;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> Dubbo::new()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .with_config({
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> r &lt;span style="color:#719e07">=&lt;/span> RootConfig::new();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">match&lt;/span> r.load() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(config) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> config,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Err&lt;/span>(_err) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> panic!(&lt;span style="color:#2aa198">&amp;#34;err: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, _err), &lt;span style="color:#586e75">// response was dropped
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .start()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#719e07">await&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">#[allow(dead_code)]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">#[derive(Default, Clone)]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">struct&lt;/span> &lt;span style="color:#268bd2">GreeterServerImpl&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#b58900">String&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// #[async_trait]
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#719e07">#[async_trait]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">impl&lt;/span> Greeter &lt;span style="color:#719e07">for&lt;/span> GreeterServerImpl {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">async&lt;/span> &lt;span style="color:#719e07">fn&lt;/span> &lt;span style="color:#268bd2">greet&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>&lt;span style="color:#268bd2">self&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> request: &lt;span style="color:#268bd2">Request&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreeterRequest&lt;span style="color:#719e07">&amp;gt;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ) -&amp;gt; &lt;span style="color:#b58900">Result&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>Response&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreeterReply&lt;span style="color:#719e07">&amp;gt;&lt;/span>, dubbo::status::Status&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;GreeterServer::greet &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, request.metadata);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(Response::new(GreeterReply {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> message: &lt;span style="color:#2aa198">&amp;#34;hello, dubbo-rust&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">async&lt;/span> &lt;span style="color:#719e07">fn&lt;/span> &lt;span style="color:#268bd2">greet_client_stream&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>&lt;span style="color:#268bd2">self&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> request: &lt;span style="color:#268bd2">Request&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>Decoding&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreeterRequest&lt;span style="color:#719e07">&amp;gt;&amp;gt;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ) -&amp;gt; &lt;span style="color:#b58900">Result&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>Response&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreeterReply&lt;span style="color:#719e07">&amp;gt;&lt;/span>, dubbo::status::Status&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#719e07">mut&lt;/span> s &lt;span style="color:#719e07">=&lt;/span> request.into_inner();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">loop&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> result &lt;span style="color:#719e07">=&lt;/span> s.next().&lt;span style="color:#719e07">await&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">match&lt;/span> result {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Some&lt;/span>(&lt;span style="color:#b58900">Ok&lt;/span>(val)) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> println!(&lt;span style="color:#2aa198">&amp;#34;result: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, val),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Some&lt;/span>(&lt;span style="color:#b58900">Err&lt;/span>(val)) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> println!(&lt;span style="color:#2aa198">&amp;#34;err: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, val),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">None&lt;/span> &lt;span style="color:#719e07">=&amp;gt;&lt;/span> &lt;span style="color:#719e07">break&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(Response::new(GreeterReply {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> message: &lt;span style="color:#2aa198">&amp;#34;hello client streaming&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">type&lt;/span> &lt;span style="color:#268bd2">greetServerStreamStream&lt;/span> &lt;span style="color:#719e07">=&lt;/span> ResponseStream;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">async&lt;/span> &lt;span style="color:#719e07">fn&lt;/span> &lt;span style="color:#268bd2">greet_server_stream&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>&lt;span style="color:#268bd2">self&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> request: &lt;span style="color:#268bd2">Request&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreeterRequest&lt;span style="color:#719e07">&amp;gt;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ) -&amp;gt; &lt;span style="color:#b58900">Result&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>Response&lt;span style="color:#719e07">&amp;lt;&lt;/span>&lt;span style="color:#268bd2">Self&lt;/span>::greetServerStreamStream&lt;span style="color:#719e07">&amp;gt;&lt;/span>, dubbo::status::Status&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;greet_server_stream: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, request.into_inner());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> data &lt;span style="color:#719e07">=&lt;/span> vec![
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Result&lt;/span>::&lt;span style="color:#719e07">&amp;lt;&lt;/span>_, dubbo::status::Status&lt;span style="color:#719e07">&amp;gt;&lt;/span>::&lt;span style="color:#b58900">Ok&lt;/span>(GreeterReply {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> message: &lt;span style="color:#2aa198">&amp;#34;msg1 from server&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Result&lt;/span>::&lt;span style="color:#719e07">&amp;lt;&lt;/span>_, dubbo::status::Status&lt;span style="color:#719e07">&amp;gt;&lt;/span>::&lt;span style="color:#b58900">Ok&lt;/span>(GreeterReply {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> message: &lt;span style="color:#2aa198">&amp;#34;msg2 from server&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Result&lt;/span>::&lt;span style="color:#719e07">&amp;lt;&lt;/span>_, dubbo::status::Status&lt;span style="color:#719e07">&amp;gt;&lt;/span>::&lt;span style="color:#b58900">Ok&lt;/span>(GreeterReply {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> message: &lt;span style="color:#2aa198">&amp;#34;msg3 from server&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> resp &lt;span style="color:#719e07">=&lt;/span> futures_util::stream::iter(data);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(Response::new(&lt;span style="color:#b58900">Box&lt;/span>::pin(resp)))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">type&lt;/span> &lt;span style="color:#268bd2">greetStreamStream&lt;/span> &lt;span style="color:#719e07">=&lt;/span> ResponseStream;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">async&lt;/span> &lt;span style="color:#719e07">fn&lt;/span> &lt;span style="color:#268bd2">greet_stream&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>&lt;span style="color:#268bd2">self&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> request: &lt;span style="color:#268bd2">Request&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>Decoding&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreeterRequest&lt;span style="color:#719e07">&amp;gt;&amp;gt;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ) -&amp;gt; &lt;span style="color:#b58900">Result&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>Response&lt;span style="color:#719e07">&amp;lt;&lt;/span>&lt;span style="color:#268bd2">Self&lt;/span>::greetStreamStream&lt;span style="color:#719e07">&amp;gt;&lt;/span>, dubbo::status::Status&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#2aa198">&amp;#34;GreeterServer::greet_stream, grpc header: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> request.metadata
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> );
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#719e07">mut&lt;/span> in_stream &lt;span style="color:#719e07">=&lt;/span> request.into_inner();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> (tx, rx) &lt;span style="color:#719e07">=&lt;/span> mpsc::channel(&lt;span style="color:#2aa198">128&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> tokio::spawn(&lt;span style="color:#719e07">async&lt;/span> &lt;span style="color:#719e07">move&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">while&lt;/span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#b58900">Some&lt;/span>(result) &lt;span style="color:#719e07">=&lt;/span> in_stream.next().&lt;span style="color:#719e07">await&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">match&lt;/span> result {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(v) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> tx.send(&lt;span style="color:#b58900">Ok&lt;/span>(GreeterReply {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> message: &lt;span style="color:#268bd2">format&lt;/span>&lt;span style="color:#719e07">!&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;server reply: {:?}&amp;#34;&lt;/span>, v.name),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#719e07">await&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .expect(&lt;span style="color:#2aa198">&amp;#34;working rx&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Err&lt;/span>(err) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#b58900">Some&lt;/span>(io_err) &lt;span style="color:#719e07">=&lt;/span> match_for_io_error(&lt;span style="color:#719e07">&amp;amp;&lt;/span>err) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> io_err.kind() &lt;span style="color:#719e07">==&lt;/span> ErrorKind::BrokenPipe {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> eprintln!(&lt;span style="color:#2aa198">&amp;#34;&lt;/span>&lt;span style="color:#cb4b16">\t&lt;/span>&lt;span style="color:#2aa198">client disconnected: broken pipe&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">break&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">match&lt;/span> tx.send(&lt;span style="color:#b58900">Err&lt;/span>(err)).&lt;span style="color:#719e07">await&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(_) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> (),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Err&lt;/span>(_err) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> &lt;span style="color:#719e07">break&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;&lt;/span>&lt;span style="color:#cb4b16">\t&lt;/span>&lt;span style="color:#2aa198">stream ended&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> out_stream &lt;span style="color:#719e07">=&lt;/span> ReceiverStream::new(rx);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(Response::new(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Box&lt;/span>::pin(out_stream) &lt;span style="color:#719e07">as&lt;/span> &lt;span style="color:#268bd2">Self&lt;/span>::greetStreamStream
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fn&lt;/span> &lt;span style="color:#268bd2">match_for_io_error&lt;/span>(err_status: &lt;span style="color:#719e07">&amp;amp;&lt;/span>&lt;span style="color:#268bd2">dubbo&lt;/span>::status::Status) -&amp;gt; &lt;span style="color:#b58900">Option&lt;/span>&lt;span style="color:#719e07">&amp;lt;&amp;amp;&lt;/span>std::io::Error&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#719e07">mut&lt;/span> err: &lt;span style="color:#719e07">&amp;amp;&lt;/span>(&lt;span style="color:#719e07">dyn&lt;/span> std::error::Error &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#b58900">&amp;#39;static&lt;/span>) &lt;span style="color:#719e07">=&lt;/span> err_status;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">loop&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#b58900">Some&lt;/span>(io_err) &lt;span style="color:#719e07">=&lt;/span> err.downcast_ref::&lt;span style="color:#719e07">&amp;lt;&lt;/span>std::io::Error&lt;span style="color:#719e07">&amp;gt;&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#b58900">Some&lt;/span>(io_err);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> err &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">match&lt;/span> err.source() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Some&lt;/span>(err) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> err,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">None&lt;/span> &lt;span style="color:#719e07">=&amp;gt;&lt;/span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#b58900">None&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="22-writing-the-streaming-client">2.2 Writing the Streaming Client&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-rust" data-lang="rust">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// ./src/greeter/client.rs
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span>&lt;span style="color:#719e07">pub&lt;/span> &lt;span style="color:#719e07">mod&lt;/span> protos {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> include!(concat!(env!(&lt;span style="color:#2aa198">&amp;#34;OUT_DIR&amp;#34;&lt;/span>), &lt;span style="color:#2aa198">&amp;#34;/org.apache.dubbo.sample.tri.rs&amp;#34;&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> dubbo::codegen::&lt;span style="color:#719e07">*&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> futures_util::StreamExt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">use&lt;/span> protos::{greeter_client::GreeterClient, GreeterRequest};
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">#[tokio::main]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">async&lt;/span> &lt;span style="color:#719e07">fn&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#719e07">mut&lt;/span> cli &lt;span style="color:#719e07">=&lt;/span> GreeterClient::new().with_uri(&lt;span style="color:#2aa198">&amp;#34;http://127.0.0.1:8888&amp;#34;&lt;/span>.to_string());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;# unary call&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> resp &lt;span style="color:#719e07">=&lt;/span> cli
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .greet(Request::new(GreeterRequest {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;message from client&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#719e07">await&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> resp &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">match&lt;/span> resp {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(resp) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> resp,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Err&lt;/span>(err) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> &lt;span style="color:#719e07">return&lt;/span> println!(&lt;span style="color:#2aa198">&amp;#34;&lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, err),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> (_parts, body) &lt;span style="color:#719e07">=&lt;/span> resp.into_parts();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;Response: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, body);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;# client stream&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> data &lt;span style="color:#719e07">=&lt;/span> vec![
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreeterRequest {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;msg1 from client streaming&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreeterRequest {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;msg2 from client streaming&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreeterRequest {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;msg3 from client streaming&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> req &lt;span style="color:#719e07">=&lt;/span> futures_util::stream::iter(data);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> resp &lt;span style="color:#719e07">=&lt;/span> cli.greet_client_stream(req).&lt;span style="color:#719e07">await&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> client_streaming_resp &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">match&lt;/span> resp {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(resp) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> resp,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Err&lt;/span>(err) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> &lt;span style="color:#719e07">return&lt;/span> println!(&lt;span style="color:#2aa198">&amp;#34;&lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, err),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> (_parts, resp_body) &lt;span style="color:#719e07">=&lt;/span> client_streaming_resp.into_parts();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;client streaming, Response: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, resp_body);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;# bi stream&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> data &lt;span style="color:#719e07">=&lt;/span> vec![
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreeterRequest {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;msg1 from client&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreeterRequest {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;msg2 from client&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreeterRequest {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;msg3 from client&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> req &lt;span style="color:#719e07">=&lt;/span> futures_util::stream::iter(data);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> bidi_resp &lt;span style="color:#719e07">=&lt;/span> cli.greet_stream(req).&lt;span style="color:#719e07">await&lt;/span>.unwrap();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> (parts, &lt;span style="color:#719e07">mut&lt;/span> body) &lt;span style="color:#719e07">=&lt;/span> bidi_resp.into_parts();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;parts: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, parts);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">while&lt;/span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#b58900">Some&lt;/span>(item) &lt;span style="color:#719e07">=&lt;/span> body.next().&lt;span style="color:#719e07">await&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">match&lt;/span> item {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(v) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;reply: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, v);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Err&lt;/span>(err) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;err: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, err);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> trailer &lt;span style="color:#719e07">=&lt;/span> body.trailer().&lt;span style="color:#719e07">await&lt;/span>.unwrap();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;trailer: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, trailer);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;# server stream&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> resp &lt;span style="color:#719e07">=&lt;/span> cli
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .greet_server_stream(Request::new(GreeterRequest {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: &lt;span style="color:#2aa198">&amp;#34;server streaming req&amp;#34;&lt;/span>.to_string(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#719e07">await&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .unwrap();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> (parts, &lt;span style="color:#719e07">mut&lt;/span> body) &lt;span style="color:#719e07">=&lt;/span> resp.into_parts();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;parts: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, parts);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">while&lt;/span> &lt;span style="color:#268bd2">let&lt;/span> &lt;span style="color:#b58900">Some&lt;/span>(item) &lt;span style="color:#719e07">=&lt;/span> body.next().&lt;span style="color:#719e07">await&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">match&lt;/span> item {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Ok&lt;/span>(v) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;reply: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, v);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">Err&lt;/span>(err) &lt;span style="color:#719e07">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;err: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, err);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">let&lt;/span> trailer &lt;span style="color:#719e07">=&lt;/span> body.trailer().&lt;span style="color:#719e07">await&lt;/span>.unwrap();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> println!(&lt;span style="color:#2aa198">&amp;#34;trailer: &lt;/span>&lt;span style="color:#2aa198">{:?}&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span>, trailer);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="3-running-the-example">3 Running the Example&lt;/h2>
&lt;ol>
&lt;li>Build&lt;/li>
&lt;/ol>
&lt;p>Run &lt;code>cargo build&lt;/code> to compile the server and client.&lt;/p></description></item></channel></rss>