其他分享
首页 > 其他分享> > 3.11 Go之RPC(模拟远程调用过程)

3.11 Go之RPC(模拟远程调用过程)

作者:互联网

3.11 Go之RPC(模拟远程调用过程)

什么是RPC框架?

RPC是指Remote Procedure Call远程过程调用

作用:

简化进程间通信的过程

RPC的作用

装通信过程,让远程的数据收发通信过程看起来就像本地的函数调用一样。

Go之RPC示例

特点:

使用channel代替Socket实现RPC过程

客户端和服务器再一个进程当中的两个goroutine中运行

实现方式:

  1. 定义客服端发送消息和封装消息的函数-->接收消息、放入消息通道、超时处理

  2. 定义服务端接收消息后的处理以及答复

示例代码:

package main

import (
   "errors"
   "fmt"
   "time"
)

/*
实现客服端和服务器再一个进程
使用channel+两个goroutine实现
*/
/* 模拟RPC客户端的请求和接收消息并封装 */
func RPCClient(ch chan string, req string) (string, error) {
   // 向服务器通道发送消息--->将接收到的信息发送到ch通道
   ch <- req

   // 使用select选择器接收服务器的消息
   select {
   case ack := <-ch:
       // 接收服务器返回的数据
       return ack, nil
   case <-time.After(time.Second):
       // 超时返回空值并抛出异常信息
       return "", errors.New("连接超时!")
  }
}

/* 模拟PRC服务器端接收客户端请求和回应 */
func RPCServer(ch chan string) {
   // 持续接收
   for {
       // 接收客户端消息
       data := <-ch

       // 打印收到的信息
       fmt.Println("接收到的信息是:", data)

       // 将结果返回给客户端--->数据放回通道
       ch <- "已收到消息!"
  }
}

/* main函数调用 */
func main() {
   // 创建通道--->客服端与服务器沟通通道
   ch := make(chan string)

   // 并发执行服务器逻辑
   go RPCServer(ch)

   // 模拟客户端请求数据
   recv, err := RPCClient(ch, "HelloWorld!")
   if err != nil {
       // 打印错误信息
       fmt.Println(err)
  }else {
       // 正常接收
       fmt.Println("接收到的信息是", recv)
  }
}

客户端请求和接收封装

/* 模拟RPC客户端的请求和接收消息并封装 */
func RPCClient(ch chan string, req string) (string, error) {
   // 向服务器通道发送消息--->将接收到的信息发送到ch通道
   ch <- req

   // 使用select选择器接收服务器的消息
   select {
   case ack := <-ch:
       // 接收服务器返回的数据
       return ack, nil
   case <-time.After(3 * time.Second):
       // 超时返回空值并抛出异常信息
       return "", errors.New("连接超时!")
  }
}

注意:

  1. 方法入口模拟socket向服务器发送一个字符串信息。服务器接收后,结束阻塞执行下一行。

  2. 使用select开始做多路复用--->select语句中的case的通道操作是同时开启的。哪个case先返回则先执行哪个case里的语句

  3. time.After使用了time包提供的函数After(),参数是 time包的一个常量,time.After返回一个通道,这个通道在指定时间后,通过通道返回当前时间。

主流程

创建一个无缓冲的字符串格式通道。将通道传给服务器的 RPCServer()函数,这个函数并发执行。使用RPCClient()函数通过ch对服务器发出RPC请求,同时接收服务器反馈数据或者等待超时

/* main函数调用 */
func main() {
   // 创建通道--->客服端与服务器沟通通道
   ch := make(chan string)

   // 并发执行服务器逻辑
   go RPCServer(ch)

   // 模拟客户端请求数据
   recv, err := RPCClient(ch, "HelloWorld!")
   if err != nil {
       // 打印错误信息
       fmt.Println(err)
  }else {
       // 正常接收
       fmt.Println("接收到的信息是", recv)
  }
}

 

标签:ch,string,3.11,RPC,Go,服务器,接收,通道
来源: https://www.cnblogs.com/JunkingBoy/p/16033293.html