Skip to content

Commit 612be32

Browse files
committed
Site updated: 2025-06-20 17:09:08
1 parent c1304ee commit 612be32

4 files changed

Lines changed: 37 additions & 9 deletions

File tree

ComputerScience/知识/RPC/index.html

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<meta property="og:description" content="Remote Procedure Call 本地函数放到服务器运行,会出现若干问题: 我怎么知道是哪个函数?Call Id 本地函数调用,可以直接用指针找到函数;但是远程过程调用不行。 因此我们需要分别在Client和Server维护一个“函数 &lt;-&gt; Call Id”的映射来确定所调用的函数。 Client如何将参数传送到Server?序列化与反序列化 本地函数调用,参数会压入栈">
2929
<meta property="og:locale" content="zh_CN">
3030
<meta property="article:published_time" content="2025-06-09T16:00:00.000Z">
31-
<meta property="article:modified_time" content="2025-06-18T07:12:51.799Z">
31+
<meta property="article:modified_time" content="2025-06-20T09:07:55.548Z">
3232
<meta property="article:author" content="SIMULEITE">
3333
<meta property="article:tag" content="知识">
3434
<meta name="twitter:card" content="summary">
@@ -141,7 +141,7 @@
141141
<div class="sidebar-panel-container">
142142
<!--noindex-->
143143
<div class="post-toc-wrap sidebar-panel">
144-
<div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#remote-procedure-call"><span class="nav-text"> Remote Procedure Call</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%B8%80%E4%B8%AAhttp%E8%AF%B7%E6%B1%82"><span class="nav-text"> 一个HTTP请求</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#grpc"><span class="nav-text"> gRPC</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#protobuf"><span class="nav-text"> Protobuf</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#stream"><span class="nav-text"> Stream</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#simple-rpc"><span class="nav-text"> Simple RPC</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#server-side-streaming-rpc"><span class="nav-text"> Server-side streaming RPC</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#client-side-streaming-rpc"><span class="nav-text"> Client-side streaming RPC</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#bidirectional-streaming-rpc"><span class="nav-text"> Bidirectional streaming RPC</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#metadata"><span class="nav-text"> MetaData</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#interceptor"><span class="nav-text"> Interceptor</span></a></li></ol></div>
144+
<div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#remote-procedure-call"><span class="nav-text"> Remote Procedure Call</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%B8%80%E4%B8%AAhttp%E8%AF%B7%E6%B1%82"><span class="nav-text"> 一个HTTP请求</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#grpc"><span class="nav-text"> gRPC</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#protobuf"><span class="nav-text"> Protobuf</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#proto2go"><span class="nav-text"> proto2go</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#stream"><span class="nav-text"> Stream</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#simple-rpc"><span class="nav-text"> Simple RPC</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#server-side-streaming-rpc"><span class="nav-text"> Server-side streaming RPC</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#client-side-streaming-rpc"><span class="nav-text"> Client-side streaming RPC</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#bidirectional-streaming-rpc"><span class="nav-text"> Bidirectional streaming RPC</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#metadata"><span class="nav-text"> MetaData</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#interceptor"><span class="nav-text"> Interceptor</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#validation"><span class="nav-text"> Validation</span></a></li></ol></div>
145145
</div>
146146
<!--/noindex-->
147147

@@ -223,7 +223,7 @@ <h1 class="post-title" itemprop="name headline">
223223
<i class="far fa-calendar-check"></i>
224224
</span>
225225
<span class="post-meta-item-text">更新于</span>
226-
<time title="修改时间:2025-06-18 15:12:51" itemprop="dateModified" datetime="2025-06-18T15:12:51+08:00">2025-06-18</time>
226+
<time title="修改时间:2025-06-20 17:07:55" itemprop="dateModified" datetime="2025-06-20T17:07:55+08:00">2025-06-20</time>
227227
</span>
228228

229229

@@ -265,6 +265,12 @@ <h2 id="protobuf"><a class="markdownIt-Anchor" href="#protobuf"></a> Protobuf</h
265265
</ul>
266266
<figure class="highlight protobuf"><table><tr><td class="code"><pre><span class="line"><span class="keyword">message </span><span class="title class_">HelloReq</span> &#123;</span><br><span class="line"> <span class="keyword">message </span><span class="title class_">InnerReq</span> &#123;</span><br><span class="line"> <span class="type">string</span> name = <span class="number">1</span>;</span><br><span class="line"> <span class="type">string</span> url = <span class="number">2</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> Gender gender = <span class="number">1</span>;</span><br><span class="line"> map&lt;<span class="type">string</span>, <span class="type">string</span>&gt; map = <span class="number">2</span>;</span><br><span class="line"> google.protobuf.Timestamp createTime = <span class="number">3</span>;</span><br><span class="line"> <span class="keyword">repeated</span> InnerReq req = <span class="number">4</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
267267
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">// -I 路径; --go_out 生成go代码; plugins=grpc:. 使用grpc拓展,使用grpc拓展生成接口代码,放在当前目录下</span><br><span class="line">protoc -I . &lt;filename&gt;.proto --go_out=plugins=grpc:.</span><br></pre></td></tr></table></figure>
268+
<h2 id="proto2go"><a class="markdownIt-Anchor" href="#proto2go"></a> proto2go</h2>
269+
<figure class="highlight protobuf"><table><tr><td class="code"><pre><span class="line"><span class="keyword">service </span><span class="title class_">Greeter</span> &#123;</span><br><span class="line"> <span class="function"><span class="keyword">rpc</span> SayHello (HelloReq) <span class="keyword">returns</span> (HelloResp)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
270+
<p>Server</p>
271+
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="keyword">type</span> GreeterServer <span class="keyword">interface</span> &#123;</span><br><span class="line"> SayHello(context.Context, *HelloReq) (*HelloReply, <span class="type">error</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">RegisterGreeterServer</span><span class="params">(s *gprc.Server, srv GreeterServer)</span></span> &#123;</span><br><span class="line"> s.RegisterService(&amp;_Greeter_serviceDesc, srv)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
272+
<p>Client</p>
273+
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="keyword">type</span> greeterClient <span class="keyword">struct</span> &#123;</span><br><span class="line"> cc grpc.ClientConnInterface</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">NewGreeterClient</span><span class="params">(cc grpc.ClientConnInterface)</span></span> GreeterClient &#123;</span><br><span class="line"> <span class="comment">// 返回一个实现了Interface所有方法的结构体</span></span><br><span class="line"> <span class="keyword">return</span> &amp;greeterClient&#123;cc&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> GreeterClient <span class="keyword">interface</span> &#123;</span><br><span class="line"> SayHello(ctx content.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloReply, <span class="type">error</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *greeterClient)</span></span> SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloReply, <span class="type">error</span>) &#123;</span><br><span class="line"> out := <span class="built_in">new</span>(HelloReply)</span><br><span class="line"> err := c.cc.Invoke(ctx, <span class="string">&quot;/Greeter/SayHello&quot;</span>, in, out, opts...)</span><br><span class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> out, <span class="literal">nil</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
268274
<h2 id="stream"><a class="markdownIt-Anchor" href="#stream"></a> Stream</h2>
269275
<h3 id="simple-rpc"><a class="markdownIt-Anchor" href="#simple-rpc"></a> Simple RPC</h3>
270276
<p>Client和Server都建立短连接。</p>
@@ -281,9 +287,17 @@ <h3 id="bidirectional-streaming-rpc"><a class="markdownIt-Anchor" href="#bidirec
281287
<figure class="highlight protobuf"><table><tr><td class="code"><pre><span class="line"><span class="keyword">service </span><span class="title class_">Greeter</span> &#123;</span><br><span class="line"> <span class="function"><span class="keyword">rpc</span> GetStream(stream StreamReq) <span class="keyword">returns</span> (stream StreamResp)</span></span><br><span class="line"><span class="function">&#125;</span></span><br></pre></td></tr></table></figure>
282288
<h2 id="metadata"><a class="markdownIt-Anchor" href="#metadata"></a> MetaData</h2>
283289
<p>gRPC和HTTP一样,可以携带一些MetaData</p>
284-
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">:authority [localhost:port]</span><br><span class="line">content-type [application/grpc]</span><br><span class="line">user-agent [grpc-gp/version]</span><br><span class="line"></span><br><span class="line">data [your_data]</span><br></pre></td></tr></table></figure>
290+
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">:authority [localhost:port]</span><br><span class="line">content-type [application/grpc]</span><br><span class="line">user-agent [grpc-gp/version]</span><br><span class="line"></span><br><span class="line">data [your_data]</span><br></pre></td></tr></table></figure>
285291
<h1 id="interceptor"><a class="markdownIt-Anchor" href="#interceptor"></a> Interceptor</h1>
286292
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">interceptorCust := <span class="function"><span class="keyword">func</span><span class="params">(ctx context.Context, req Interface&#123;&#125;, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler)</span></span> (resp Interface&#123;&#125;, err <span class="type">error</span>) &#123;</span><br><span class="line"> fmt.Println(<span class="string">&quot;接收到新请求: &quot;</span>, req)</span><br><span class="line"> start := time.Now()</span><br><span class="line"></span><br><span class="line"> res, err := handler(ctx, req)</span><br><span class="line"></span><br><span class="line"> fmt.Println(<span class="string">&quot;请求完成,耗时: &quot;</span>, time.Since(start))</span><br><span class="line"> <span class="keyword">return</span> res, err</span><br><span class="line">&#125;</span><br><span class="line">opt := grpc.UnaryInterceptor(interceptorCust)</span><br><span class="line">g := grpc.NewServer(opt)</span><br></pre></td></tr></table></figure>
293+
<h1 id="validation"><a class="markdownIt-Anchor" href="#validation"></a> Validation</h1>
294+
<p>plugin: protoc-gen-validate</p>
295+
<figure class="highlight protobuf"><table><tr><td class="code"><pre><span class="line"><span class="keyword">message </span><span class="title class_">Person</span> &#123;</span><br><span class="line"> <span class="comment">// id &gt; 999</span></span><br><span class="line"> <span class="type">uint64</span> id = <span class="number">1</span> [(validate.rules).<span class="type">uint64</span>.gt = <span class="number">999</span>];</span><br><span class="line"> <span class="comment">// email validation</span></span><br><span class="line"> <span class="type">string</span> email = <span class="number">2</span> [(validate.rules).<span class="type">string</span>.email = <span class="literal">true</span>];</span><br><span class="line"> <span class="comment">// custom validation</span></span><br><span class="line"> <span class="type">string</span> name = <span class="number">3</span> [(validate.rules).<span class="type">string</span> = &#123;</span><br><span class="line"> pattern: <span class="string">&quot;^[0-9]&amp;&quot;</span>,</span><br><span class="line"> max_bytes: <span class="number">256</span>,</span><br><span class="line"> &#125;];</span><br><span class="line"> <span class="comment">// not null</span></span><br><span class="line"> Location home = <span class="number">4</span> [(validate.rules).message.<span class="keyword">required</span> = ture];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">message </span><span class="title class_">Location</span> &#123;</span><br><span class="line"> <span class="comment">// multi-args validation</span></span><br><span class="line"> <span class="type">double</span> lat = <span class="number">1</span> [(validate.rules).<span class="type">double</span> = &#123; gte: -<span class="number">90</span>, lte: <span class="number">90</span> &#125;];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
296+
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">protoc --validate_out=&quot;lang=go:.&quot;</span><br></pre></td></tr></table></figure>
297+
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">p := <span class="built_in">new</span>(Person)</span><br><span class="line"><span class="comment">// throw error automatically</span></span><br><span class="line">err := p.Validate()</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line"> <span class="built_in">panic</span>(err)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
298+
<p>搭配拦截器</p>
299+
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">interceptor</span><span class="params">(ctx, req, info, handler)</span></span> (resp, err) &#123;</span><br><span class="line"> <span class="keyword">if</span> r, ok := req.(Validator); ok &#123;</span><br><span class="line"> <span class="keyword">if</span> err := r.Validate(); err != <span class="literal">nil</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">nil</span>, status.Error(codes.InvalidArgument, err.Error())</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> handler(ctx, req)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
300+
287301
</div>
288302

289303

0 commit comments

Comments
 (0)