当前位置: 首页 > news >正文

go语言rpc初体验

go语言rpc初体验

package mainimport ("net""net/rpc"
)// 注册一个接口进来
type HelloService struct {
}func (s *HelloService) Hello(request string, replay *string) error {//返回值是通过修改replay的值*replay = "hello " + requestreturn nil
}// go语言内置rpc包
func main() {//注册名字 实例化一个severlistener, _ := net.Listen("tcp", ":1234") //监听//注册处理handle_ = rpc.RegisterName("HelloService", &HelloService{})//启动服务conn, _ := listener.Accept() //当一个新的连接进来的时候,生成套接字rpc.ServeConn(conn)          //调用一次连接就结束
}
package mainimport ("fmt""net/rpc"
)func main() {//建立连接client, err := rpc.Dial("tcp", "localhost:1234")if err != nil {panic("连接失败")}//var replay *string //reading body gob:DecodeValue of unassignable value 传递的nil 没有地址//var replay *string = new(string) //new 是分配一个空间 第一种方法var replay string //string有默认值 第二种方法err = client.Call("HelloService.Hello", "bobby", &replay)if err != nil {panic("调用失败")}fmt.Println(replay)
}

一连串的代码大部分都是net的包好像和rpc没有关系?
答:不行,rpc调用中有几个问题需要解决:1:call id,2序列化和反序列化
可以跨语言调用呢? 1. go语言的rpc的序列化协议是什么(Gob) 2. 能否替换成常见的序列化

替换rpc的传输协议为json

package mainimport ("net""net/rpc""net/rpc/jsonrpc"
)// 注册一个接口进来
type HelloService struct {
}func (s *HelloService) Hello(request string, replay *string) error {//返回值是通过修改replay的值*replay = "hello " + requestreturn nil
}// go语言内置rpc包
func main() {//注册名字 实例化一个severlistener, _ := net.Listen("tcp", ":1234") //监听//注册处理handle_ = rpc.RegisterName("HelloService", &HelloService{})for { //如果使用死循环,有一个弊端如果同时多个客户端处理,需要一个一个处理,所以需要加协程//启动服务conn, _ := listener.Accept() //当一个新的连接进来的时候,生成套接字//但使用指定的编解码器,以编码请求主体和解码回复主体。go rpc.ServeCodec(jsonrpc.NewServerCodec(conn)) //后面传来的东西,然后支持的编码都可以}}

如果使用死循环,有一个弊端如果同时多个客户端处理,需要一个一个处理,所以需要加协程

package mainimport ("fmt""net""net/rpc""net/rpc/jsonrpc"
)func main() {//建立连接conn, err := net.Dial("tcp", "localhost:1234")if err != nil {panic("连接失败")}//jsonrpc.NewClientCodec(conn) 包装连接变成一个新的connclient := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn)) //因为他是json的格式var replay string                                              //string有默认值 第二种方法err = client.Call("HelloService.Hello", "bobby", &replay)      //发送数据格式为jsonif err != nil {panic("调用失败")}fmt.Println(replay)
}

修改rpc调用代码

client.go

package mainimport ("awesomeProject123/new_helloworld/client_proxy""fmt"
)func main() {//建立连接//1 只想写业务逻辑,不想关注每个函数的名称//客户端部分client := client_proxy.NewHelloServiceClient("tcp", "localhost:1234")//jsonrpc.NewClientCodec(conn) 包装连接变成一个新的connvar replay string                     //string有默认值 第二种方法err := client.Hello("bobby", &replay) //发送数据格式为jsonif err != nil {panic("调用失败")}fmt.Println(replay)
}

client_proxy.go

package client_proxyimport ("awesomeProject123/new_helloworld/handler""net/rpc"
)type HelloServerStub struct {*rpc.Client
}// NewHelloServiceClient 在go语言中没有类、对象,就意味着没有初始化方法
func NewHelloServiceClient(protol, address string) HelloServerStub {conn, err := rpc.Dial(protol, address)if err != nil {panic("connect error!")}return HelloServerStub{conn}
}func (c *HelloServerStub) Hello(request string, replay *string) error {err := c.Call(handler.HelloServiceName+".Hello", request, replay)if err != nil {return err}return nil
}

server.go

package mainimport ("awesomeProject123/new_helloworld/handler""awesomeProject123/new_helloworld/server_proxy""net""net/rpc"
)// go语言内置rpc包
func main() {//注册名字 实例化一个severlistener, _ := net.Listen("tcp", ":1234") //监听//注册处理handler_ = server_proxy.RegisterHelloService(&handler.NewHelloService{})//_ = rpc.RegisterName(handler.HelloServiceName, &handler.HelloService{})for {//启动服务conn, _ := listener.Accept() //当一个新的连接进来的时候,生成套接字rpc.ServeConn(conn)          //调用一次连接就结束}
}

server_proxy.go

package server_proxyimport ("awesomeProject123/new_helloworld/handler""net/rpc"
)type HelloServicer interface {Hello(request string, replay *string) error
}// RegisterHelloService 解耦  --我们关心的是函数,鸭子类型
func RegisterHelloService(srv HelloServicer) error {return rpc.RegisterName(handler.HelloServiceName, srv)
}

protoc安装

https://github.com/protocolbuffers/protobuf/releases

http://www.lryc.cn/news/229546.html

相关文章:

  • 嵌入式LINUX——环境搭建 windows、虚拟机、开发板 互ping
  • 评论:AlexNet和CaffeNet有何区别?
  • 什么是 IT 资产管理(ITAM),以及它如何简化业务
  • git快速上传代码
  • stable diffusion comfyui的api使用教程
  • Swift中的strong, weak, unowned
  • Linux命令——ssh
  • 在qml中,text如何左对齐,对齐方式有哪些?如何换行?
  • 【Rust 易学教程】第 1 天:Rust 基础,基本语法
  • Linux(命令)——结合实际场景的命令 查找Java安装位置命令
  • C语言基础 -- scanf函数的返回值及其应用
  • mac 安装 selenium + chrome driver
  • 【阿里云】函数计算 X 通义千问快速部署
  • el-table本地与线上的样式不一致出现错乱
  • C语言--从键盘输入当月利润I,求应发奖金总数。
  • 记忆科技携手中国电信,一站式存储打造坚实数字底座
  • 基于ssm的学生档案管理系统(有报告)。Javaee项目,ssm项目。
  • 阿里云服务中断事件:原因、影响与解决方案
  • 搜维尔科技:「体育类」Movella Xsens极限运动捕捉测试
  • CSS常用示例100+ 【目录】
  • Shopee买家通系统之注册虾皮买家号大概需要多少成本
  • 华为层层“能力外溢”,让数智世界一触即达——选择华为,让您的企业轻松数智化
  • MHA实验和架构
  • C语言——函数
  • DDR SDRAM 学习笔记
  • RocketMQ(4.9.4)学习笔记 - 安装部署
  • 虚拟局域网
  • 【PG】PostgreSQL 预写日志(WAL)、checkpoint、LSN
  • 一文了解VR全景拍摄设备如何选择,全景图片如何处理
  • Linux下docker安装mysql8.0