| <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – browser</title><link>https://dubbo.apache.org/zh-cn/tags/browser/</link><description>Recent content in browser on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sat, 07 Oct 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://dubbo.apache.org/zh-cn/tags/browser/index.xml" rel="self" type="application/rss+xml"/><item><title>Blog: Web 浏览器页面也能访问dubbo、grpc微服务?Dubbo-js alpha版本正式发布</title><link>https://dubbo.apache.org/zh-cn/blog/2023/10/07/web-%E6%B5%8F%E8%A7%88%E5%99%A8%E9%A1%B5%E9%9D%A2%E4%B9%9F%E8%83%BD%E8%AE%BF%E9%97%AEdubbogrpc%E5%BE%AE%E6%9C%8D%E5%8A%A1dubbo-js-alpha%E7%89%88%E6%9C%AC%E6%AD%A3%E5%BC%8F%E5%8F%91%E5%B8%83/</link><pubDate>Sat, 07 Oct 2023 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/blog/2023/10/07/web-%E6%B5%8F%E8%A7%88%E5%99%A8%E9%A1%B5%E9%9D%A2%E4%B9%9F%E8%83%BD%E8%AE%BF%E9%97%AEdubbogrpc%E5%BE%AE%E6%9C%8D%E5%8A%A1dubbo-js-alpha%E7%89%88%E6%9C%AC%E6%AD%A3%E5%BC%8F%E5%8F%91%E5%B8%83/</guid><description> |
| <p>基于 Dubbo3 定义的 Triple 协议,你可以轻松编写浏览器、gRPC 兼容的 RPC 服务,并让这些服务同时运行在 HTTP/1 和 HTTP/2 上。<a href="https://github.com/apache/dubbo-js/">Dubbo TypeScript SDK</a> 支持使用 IDL 或编程语言特有的方式定义服务,并提供一套轻量的 APl 来发布或调用这些服务。</p> |
| <p>Dubbo-js 已于 9 月份发布支持 Dubbo3 协议的首个 alpha 版本,它的发布将有机会彻底改变微服务前后端的架构与通信模式,让你能直接在浏览器页面或web服务器中访问后端 Dubbo RPC 服务。目前项目快速发展中,对参与 apache/dubbo-js 项目感兴趣的开发者,欢迎搜索钉钉群:<strong>29775027779</strong> 加入开发者群组。</p> |
| <p><img src="https://dubbo.apache.org/imgs/blog/2023/9/web/img.png" alt="Web 浏览器页面也能访问dubbo、grpc微服务"></p> |
| <h1 id="浏览器-web-应用示例">浏览器 Web 应用示例</h1> |
| <p>本示例演示了如何使用 dubbo-js 开发运行在浏览器上的 web 应用程序,web 页面将调用 dubbo node.js 开发的后端服务并生成页面内容。本示例演示基于 IDL 和非 IDL 两种编码模式。</p> |
| <p><img src="https://dubbo.apache.org/imgs/blog/2023/9/web/img_1.png" alt="Web 浏览器页面也能访问dubbo、grpc微服务"></p> |
| <h2 id="idl-模式">IDL 模式</h2> |
| <h3 id="前置条件">前置条件</h3> |
| <p>首先,我们将使用 Vite 来生成我们的前端项目模板,它内置了我们稍后需要的所有功能支持。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>npm create vite@latest -- dubbo-web-example --template react-ts |
| </span></span><span style="display:flex;"><span><span style="color:#b58900">cd</span> dubbo-web-example |
| </span></span><span style="display:flex;"><span>npm install |
| </span></span></code></pre></div><p>因为使用 Protocol Buffer 的原因,我们首先需要安装相关的代码生成工具,这包括 <code>@bufbuild/protoc-gen-es</code>、<code>@bufbuild/protobuf</code>、<code>@apachedubbo/protoc-gen-apache-dubbo-es</code>、<code>@apachedubbo/dubbo</code>。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>npm install @bufbuild/protoc-gen-es @bufbuild/protobuf @apachedubbo/protoc-gen-apache-dubbo-es @apachedubbo/dubbo |
| </span></span></code></pre></div><h3 id="使用-proto-定义服务">使用 Proto 定义服务</h3> |
| <p>现在,使用 Protocol Buffer (IDL) 来定义一个 Dubbo 服务。</p> |
| <p>src 下创建 util/proto 目录,并生成文件</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>mkdir -p src/util/proto <span style="color:#719e07">&amp;&amp;</span> touch src/util/proto/example.proto |
| </span></span></code></pre></div><p>写入内容</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span>syntax <span style="color:#719e07">=</span> <span style="color:#2aa198">&#34;proto3&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">package</span> apache<span style="color:#719e07">.</span>dubbo.demo.example.v1; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">message</span> <span style="color:#268bd2">SayRequest</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">string</span> sentence <span style="color:#719e07">=</span> <span style="color:#2aa198">1</span>; |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">message</span> <span style="color:#268bd2">SayResponse</span> { |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">string</span> sentence <span style="color:#719e07">=</span> <span style="color:#2aa198">1</span>; |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">service</span> ExampleService { |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">rpc</span> Say(SayRequest) <span style="color:#719e07">returns</span> (SayResponse) {} |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><p>这个文件声明了一个叫做 <code>ExampleService</code> 的服务,为这个服务定义了 <code>Say</code> 方法以及它的请求参数 <code>SayRequest</code> 和返回值 <code>SayResponse</code>。</p> |
| <h3 id="生成代码">生成代码</h3> |
| <p>创建 gen 目录,作为生成文件放置的目标目录</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>mkdir -p src/util/gen |
| </span></span></code></pre></div><p>运行以下命令,利用 <code>protoc-gen-es</code>、<code>protoc-gen-apache-dubbo-es</code> 等插件在 gen 目录下生成代码文件</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#268bd2">PATH</span><span style="color:#719e07">=</span><span style="color:#268bd2">$PATH</span>:<span style="color:#719e07">$(</span><span style="color:#b58900">pwd</span><span style="color:#719e07">)</span>/node_modules/.bin <span style="color:#cb4b16">\ |
| </span></span></span><span style="display:flex;"><span><span style="color:#cb4b16"></span> protoc -I src/util/proto <span style="color:#cb4b16">\ |
| </span></span></span><span style="display:flex;"><span><span style="color:#cb4b16"></span> --es_out src/util/gen <span style="color:#cb4b16">\ |
| </span></span></span><span style="display:flex;"><span><span style="color:#cb4b16"></span> --es_opt <span style="color:#268bd2">target</span><span style="color:#719e07">=</span>ts <span style="color:#cb4b16">\ |
| </span></span></span><span style="display:flex;"><span><span style="color:#cb4b16"></span> --apache-dubbo-es_out src/util/gen <span style="color:#cb4b16">\ |
| </span></span></span><span style="display:flex;"><span><span style="color:#cb4b16"></span> --apache-dubbo-es_opt <span style="color:#268bd2">target</span><span style="color:#719e07">=</span>ts <span style="color:#cb4b16">\ |
| </span></span></span><span style="display:flex;"><span><span style="color:#cb4b16"></span> example.proto |
| </span></span></code></pre></div><p>运行命令后,应该可以在目标目录中看到以下生成的文件:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>├── src |
| </span></span><span style="display:flex;"><span>│ ├── util |
| </span></span><span style="display:flex;"><span>│ │ ├── gen |
| </span></span><span style="display:flex;"><span>│ │ │ ├── example_dubbo.ts |
| </span></span><span style="display:flex;"><span>│ │ │ └── example_pb.ts |
| </span></span><span style="display:flex;"><span>│ │ └── proto |
| </span></span><span style="display:flex;"><span>│ │ └── example.proto |
| </span></span></code></pre></div><h3 id="创建-app">创建 App</h3> |
| <p>需要先下载 <code>@apachedubbo/dubbo-web</code></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>npm install @apachedubbo/dubbo-web |
| </span></span></code></pre></div><p>现在我们可以从包中导入服务并设置一个客户端。在 App.tsx 中添加以下内容:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#268bd2">import</span> { useState } <span style="color:#268bd2">from</span> <span style="color:#2aa198">&#34;react&#34;</span>; |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">import</span> <span style="color:#2aa198">&#34;./App.css&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">import</span> { createPromiseClient } <span style="color:#268bd2">from</span> <span style="color:#2aa198">&#34;@apachedubbo/dubbo&#34;</span>; |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">import</span> { createDubboTransport } <span style="color:#268bd2">from</span> <span style="color:#2aa198">&#34;@apachedubbo/dubbo-web&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">// Import service definition that you want to connect to. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#268bd2">import</span> { ExampleService } <span style="color:#268bd2">from</span> <span style="color:#2aa198">&#34;./util/gen/example_dubbo&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">// The transport defines what type of endpoint we&#39;re hitting. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75">// In our example we&#39;ll be communicating with a Dubbo endpoint. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#268bd2">const</span> transport <span style="color:#719e07">=</span> createDubboTransport({ |
| </span></span><span style="display:flex;"><span> baseUrl<span style="color:#719e07">:</span> <span style="color:#2aa198">&#34;http://localhost:8080&#34;</span>, |
| </span></span><span style="display:flex;"><span>}); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">// Here we make the client itself, combining the service |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75">// definition with the transport. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#268bd2">const</span> client <span style="color:#719e07">=</span> createPromiseClient(ExampleService, transport, { serviceGroup<span style="color:#719e07">:</span> <span style="color:#2aa198">&#39;dubbo&#39;</span>, serviceVersion<span style="color:#719e07">:</span> <span style="color:#2aa198">&#39;1.0.0&#39;</span> }); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">function</span> App() { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">const</span> [inputValue, setInputValue] <span style="color:#719e07">=</span> useState(<span style="color:#2aa198">&#34;&#34;</span>); |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">const</span> [messages, setMessages] <span style="color:#719e07">=</span> useState<span style="color:#719e07">&lt;</span> |
| </span></span><span style="display:flex;"><span> { |
| </span></span><span style="display:flex;"><span> fromMe: <span style="color:#dc322f">boolean</span>; |
| </span></span><span style="display:flex;"><span> message: <span style="color:#dc322f">string</span>; |
| </span></span><span style="display:flex;"><span> }[] |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">&gt;</span>([]); |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> ( |
| </span></span><span style="display:flex;"><span> &lt;&gt; |
| </span></span><span style="display:flex;"><span> &lt;<span style="color:#268bd2">ol</span>&gt; |
| </span></span><span style="display:flex;"><span> {messages.map((msg, index) <span style="color:#719e07">=&gt;</span> ( |
| </span></span><span style="display:flex;"><span> &lt;<span style="color:#268bd2">li</span> key<span style="color:#719e07">=</span>{index}&gt;{<span style="color:#586e75">`</span><span style="color:#2aa198">${</span>msg.fromMe <span style="color:#719e07">?</span> <span style="color:#2aa198">&#34;ME:&#34;</span> <span style="color:#719e07">:</span> <span style="color:#2aa198">&#34;Dubbo Server:&#34;</span><span style="color:#2aa198">}</span><span style="color:#586e75"> </span><span style="color:#2aa198">${</span>msg.message<span style="color:#2aa198">}</span><span style="color:#586e75">`</span>}&lt;/<span style="color:#268bd2">li</span>&gt; |
| </span></span><span style="display:flex;"><span> ))} |
| </span></span><span style="display:flex;"><span> &lt;/<span style="color:#268bd2">ol</span>&gt; |
| </span></span><span style="display:flex;"><span> &lt;<span style="color:#268bd2">form</span> |
| </span></span><span style="display:flex;"><span> onSubmit<span style="color:#719e07">=</span>{<span style="color:#268bd2">async</span> (e) <span style="color:#719e07">=&gt;</span> { |
| </span></span><span style="display:flex;"><span> e.preventDefault(); |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// Clear inputValue since the user has submitted. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> setInputValue(<span style="color:#2aa198">&#34;&#34;</span>); |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// Store the inputValue in the chain of messages and |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// mark this message as coming from &#34;me&#34; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> setMessages((prev) <span style="color:#719e07">=&gt;</span> [ |
| </span></span><span style="display:flex;"><span> ...prev, |
| </span></span><span style="display:flex;"><span> { |
| </span></span><span style="display:flex;"><span> fromMe: <span style="color:#dc322f">true</span>, |
| </span></span><span style="display:flex;"><span> message: <span style="color:#dc322f">inputValue</span>, |
| </span></span><span style="display:flex;"><span> }, |
| </span></span><span style="display:flex;"><span> ]); |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">const</span> response <span style="color:#719e07">=</span> <span style="color:#719e07">await</span> client.say({ |
| </span></span><span style="display:flex;"><span> sentence: <span style="color:#dc322f">inputValue</span>, |
| </span></span><span style="display:flex;"><span> }); |
| </span></span><span style="display:flex;"><span> setMessages((prev) <span style="color:#719e07">=&gt;</span> [ |
| </span></span><span style="display:flex;"><span> ...prev, |
| </span></span><span style="display:flex;"><span> { |
| </span></span><span style="display:flex;"><span> fromMe: <span style="color:#dc322f">false</span>, |
| </span></span><span style="display:flex;"><span> message: <span style="color:#dc322f">response.sentence</span>, |
| </span></span><span style="display:flex;"><span> }, |
| </span></span><span style="display:flex;"><span> ]); |
| </span></span><span style="display:flex;"><span> }} |
| </span></span><span style="display:flex;"><span> &gt; |
| </span></span><span style="display:flex;"><span> &lt;<span style="color:#268bd2">input</span> value<span style="color:#719e07">=</span>{inputValue} onChange<span style="color:#719e07">=</span>{(e) <span style="color:#719e07">=&gt;</span> setInputValue(e.target.value)} /&gt; |
| </span></span><span style="display:flex;"><span> &lt;<span style="color:#268bd2">button</span> type<span style="color:#719e07">=</span><span style="color:#2aa198">&#34;submit&#34;</span>&gt;Send&lt;/<span style="color:#268bd2">button</span>&gt; |
| </span></span><span style="display:flex;"><span> &lt;/<span style="color:#268bd2">form</span>&gt; |
| </span></span><span style="display:flex;"><span> &lt;/&gt; |
| </span></span><span style="display:flex;"><span> ); |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">export</span> <span style="color:#719e07">default</span> App; |
| </span></span></code></pre></div><p>执行以下命令,即可得到样例页面</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>npm run dev |
| </span></span></code></pre></div><h3 id="启动-server">启动 Server</h3> |
| <p>接下来我们需要启动 Server,可以使用 Java、Go、Node.js 等 Dubbo 支持的任一语言开发 Server。这里我们采用 Dubbo 服务嵌入的 Node.js 服务器,具体可参考 <a href="https://github.com/apache/dubbo-js/tree/dubbo3/example/dubbo-node-example">Node.js 开发 Dubbo 后端服务</a> 中的操作步骤。</p> |
| <p>不过需要注意,我们额外需要修改 Node.js 示例:引入 @fastify/cors 来解决前端请求的跨域问题</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>npm install @fastify/cors |
| </span></span></code></pre></div><p>需要在 server.ts 文件下修改</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span>... |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">import</span> cors <span style="color:#268bd2">from</span> <span style="color:#2aa198">&#34;@fastify/cors&#34;</span>; |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span>... |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">async</span> <span style="color:#268bd2">function</span> main() { |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">const</span> server <span style="color:#719e07">=</span> fastify(); |
| </span></span><span style="display:flex;"><span> ... |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">await</span> server.register(cors, { |
| </span></span><span style="display:flex;"><span> origin: <span style="color:#dc322f">true</span>, |
| </span></span><span style="display:flex;"><span> }); |
| </span></span><span style="display:flex;"><span> ... |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">await</span> server.listen({ host<span style="color:#719e07">:</span> <span style="color:#2aa198">&#34;localhost&#34;</span>, port: <span style="color:#dc322f">8080</span> }); |
| </span></span><span style="display:flex;"><span> ... |
| </span></span><span style="display:flex;"><span>} |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">void</span> main(); |
| </span></span></code></pre></div><p>最后,运行代码启动服务</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>npx tsx server.ts |
| </span></span></code></pre></div><h2 id="无-idl-模式">无 IDL 模式</h2> |
| <p>在接下来的版本中,我们将继续提供无 IDL 模式的通信支持,这样就可以更方便的访问无 IDL 的后端服务。在这里,我们先快速的看一下无 IDL 模式的使用方式。</p> |
| <p>同样需要先安装 <code>@apachedubbo/dubbo</code>、<code>@apachedubbo/dubbo-web</code></p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>npm install @apachedubbo/dubbo @apachedubbo/dubbo-web |
| </span></span></code></pre></div><p>现在就可以一个启动一个客户端,并发起调用了。App.tsx 中的代码与 IDL 模式基本一致,区别点在于以下内容:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75">// set backend server to connect |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#268bd2">const</span> transport <span style="color:#719e07">=</span> createDubboTransport({ |
| </span></span><span style="display:flex;"><span> baseUrl<span style="color:#719e07">:</span> <span style="color:#2aa198">&#34;http://localhost:8080&#34;</span>, |
| </span></span><span style="display:flex;"><span>}); |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">// init client |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#268bd2">const</span> client <span style="color:#719e07">=</span> createPromiseClient(transport); |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">function</span> App() { |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// call remote Dubbo service |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#268bd2">const</span> response <span style="color:#719e07">=</span> <span style="color:#719e07">await</span> client.call( |
| </span></span><span style="display:flex;"><span> <span style="color:#2aa198">&#34;apache.dubbo.demo.example.v1.ExampleService&#34;</span>, |
| </span></span><span style="display:flex;"><span> <span style="color:#2aa198">&#34;say&#34;</span>, |
| </span></span><span style="display:flex;"><span> { |
| </span></span><span style="display:flex;"><span> sentence: <span style="color:#dc322f">inputValue</span>, |
| </span></span><span style="display:flex;"><span> }); |
| </span></span><span style="display:flex;"><span>} |
| </span></span></code></pre></div><p>执行以下命令,即可得到样例页面</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>npm run dev |
| </span></span></code></pre></div><h1 id="总结">总结</h1> |
| <p>直接在浏览器页面或web服务器中访问后端 Dubbo RPC 服务!Dubbo Triple 协议升级以及 Dubbo javascript sdk 的发布,对整个微服务体系是一个非常有力的补充,期待看到它能改变未来整个微服务架构以及前后端通信模式。</p> |
| <p>Dubbo-js 刚刚在 9 月份发布了支持 Dubbo3 Triple 协议的首个 alpha 版本,目前项目正处于快速发展中,对参与 apache/dubbo-js 项目感兴趣的开发者,欢迎通过以下方式加入组织:</p> |
| <ul> |
| <li>搜索钉钉群:<strong>29775027779</strong> 加入开发者群组。</li> |
| <li>关注该公众号 <code>apachedubbo</code>,回复 &ldquo;dubbojs&rdquo; 接受邀请加入开发组</li> |
| </ul></description></item></channel></rss> |