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

南山区做网站做网站的步骤

南山区做网站,做网站的步骤,温州网站推广站建设,做视频聊天网站这里我们来实现这个RPC的client端 为了实现RPC的效果,我们调用的Hello方法,即server端的方法,应该是由代理来调用,让proxy里面封装网络请求,消息的发送和接受处理。而上一篇文章提到的服务端的代理已经在.rpc.go文件中…

这里我们来实现这个RPC的client端

为了实现RPC的效果,我们调用的Hello方法,即server端的方法,应该是由代理来调用,让proxy里面封装网络请求,消息的发送和接受处理。而上一篇文章提到的服务端的代理已经在.rpc.go文件中实现,我们将客户端的实现也写在这里

ClientProxy

// 客户端代理接口
type HelloClientProxy interface  {Hello(ctx context.Context, in *HelloRequest, opts ...client.Option) (*HelloReply, error)
}// 客户端代理实现
type HelloClientProxyImpl struct {client client.Clientopts   []client.Option
}// 创建客户端代理
func NewHelloClientProxy(opts ...client.Option) HelloClientProxy {return &HelloClientProxyImpl{client: client.DefaultClient,opts:   opts,}
}
  • 这里的HelloClientProxyImpl其中的client类主要是负责invoke方法,抽象网络IO和编解码,opts主要是记录客户端启动时传入的配置项,如server的ip地址等
  • 创建出客户端代理,我们就可以通过代理来调用Hello方法

// 实现Hello方法
func (c *HelloClientProxyImpl) Hello(ctx context.Context, req *HelloRequest, opts ...client.Option) (*HelloReply, error) {// 创建一个msg结构,存储service相关的数据,如serviceName等,并放到context中// 用msg结构可以避免在context中太多withValue传递过多的参数msg := internel.NewMsg()msg.WithServiceName("helloworld")msg.WithMethodName("Hello")ctx = context.WithValue(ctx, internel.ContextMsgKey, msg)rsp := &HelloReply{}// 这里需要将opts添加前面newProxy时传入的optsnewOpts := append(c.opts, opts...)err := c.client.Invoke(ctx, req, rsp, newOpts...)if err != nil {return nil, err}return rsp, nil
}
  • 这里需要明确service的名字和对应方法,为了后续封装在协议数据里,到达server端才能正确路由。当代理类实现了这个Hello后,我们就可以通过proxy.Hello得到相应结果,Invoke方法隐藏了具体的网络处理,我们跟进Invoke方法

Client(clientTransPort)

上文提到,client类主要处理invoke方法,我们可以预见它的职责就是,

  1. 序列化请求体
  2. 编码
  3. 发送请求,接受响应
  4. 解码
  5. 反序列化响应体
  6. 返回客户端
    为了代码的解耦,我们和server的处理一样,将以上操作放到clientTransPort上,client持有transPort,让transPort处理以上的逻辑

// 实现Send方法
func (c *clientTransport) Send(ctx context.Context, reqBody interface{}, rspBody interface{}, opt *ClientTransportOption) error {// 获取连接// TODO 这里的连接后续可以优化从连接池获取conn, err := net.Dial("tcp", opt.Address)if err != nil {return err}defer conn.Close()// reqbody序列化reqData, err := codec.Marshal(reqBody)if err != nil {return err}// reqbody编码,返回请求帧framedata, err := opt.Codec.Encode(ctx, reqData)if err != nil {return err}// 写数据到连接中err = c.tcpWriteFrame(ctx, conn, framedata)if err != nil {return err}// 读取tcp帧rspDataBuf, err := c.tcpReadFrame(ctx, conn)if err != nil {return err}// 获取msgctx, msg := internel.GetMessage(ctx)// rspDataBuf解码,提取响应体数据rspData, err := opt.Codec.Decode(msg, rspDataBuf)if err != nil {return err}// 将rspData反序列化为rspBodyerr = codec.Unmarshal(rspData, rspBody)if err != nil {return err}return nil
}
  • 序列化是根据protobuf协议,编码的格式我们之间写Server的时候提到,我们需要将数据编码成以下格式:

  • 当编码完成后,我们就需要写数据到连接中,并监听该连接的数据,当有数据后,我们再依次解码得到响应体,再将响应体反序列化,返回客户端。

  • 写数据到连接和读连接中的数据也很简单,这里我们直接开启一个连接,调用Write写,而codec.ReadFrame在server端的时候已经介绍过

func (c *clientTransport) tcpWriteFrame(ctx context.Context, conn net.Conn, frame []byte) error {// 写入tcp_, err := conn.Write(frame)if err != nil {return fmt.Errorf("write frame error: %v", err)}return nil
}func (c *clientTransport) tcpReadFrame(ctx context.Context, conn net.Conn) ([]byte, error) {return codec.ReadFrame(conn)
}

效果测试

至此client端处理完毕,我们来看看效果:

//client端的测试main.go:
func main() {c := pb.NewHelloClientProxy(client.WithTarget("127.0.0.1:8000"))if c == nil {fmt.Println("Failed to create client")return}rsp, err := c.Hello(context.Background(), &pb.HelloRequest{Msg: "world"})if err != nil {fmt.Println("RPC call error:", err)return}fmt.Println("Response:", rsp.Msg)
}// server端的测试的main.go
func main() {// Create a new server instances := server.NewServer()// Register the HelloService with the serverpb.RegisterHelloServer(s, &HelloServerImpl{})// Start the server on port 50051if err := s.Serve(":8000"); err != nil {panic(err)}fmt.Print("启动成功")
}// 创建一个HelloServer的实现类
type HelloServerImpl struct{}
// 实现HelloServer接口的Hello方法
func (h *HelloServerImpl) Hello(req *pb.HelloRequest) (*pb.HelloReply, error) {// 这里可以实现具体的业务逻辑reply := &pb.HelloReply{Msg: "Hello " + req.Msg,}return reply, nil
}

server端启动:

server端接收到client的连接请求:
在这里插入图片描述

client收到响应:
在这里插入图片描述

现在version1开发完了,目前的版本主要是实现基础功能,并且为了考虑后续的扩展性做了比较多的解耦,在后面的版本,我们可以逐渐提升这个rpc的性能和融入更多的功能

http://www.dtcms.com/wzjs/147889.html

相关文章:

  • 建站系统下载 discuz搜索引擎优化的方法有哪些?
  • 整站策划营销型网站建设网站优化搜索引擎排名谷歌
  • 手工包网站建设策划书怎么做微信小程序
  • 信誉好的永州网站建设平台优化是什么意思
  • IIS 网站 消失网站推广优化外包公司哪家好
  • seo网站建设方案做一个个人网站
  • 用什么软件可以做网站动态如何做好网站的推广工作
  • wordpress什么插件好手机百度seo快速排名
  • 新手如何制作网站谷歌google官网入口
  • wordpress留言板制作关键词排名优化公司成都
  • 这样制作公司网站seo排名工具给您好的建议下载官网
  • 建立网站服务的公司网站百度开户推广多少钱
  • 长治做网站杭州优化排名哪家好
  • 如何做贷款网站推广广告公司推广渠道
  • 面包类网站设计杭州网站
  • 怎么做属于自己的领券网站广告联盟平台哪个好
  • 中等职业学校示范建设专题网站网络推广一般都干啥
  • 西安网站排名优化长沙企业网站建设报价
  • 广东省省的建设厅官方网站网络整合营销方案ppt
  • wgcz公司网站谷歌广告投放步骤
  • 如何自己建站网站制作培训报名
  • 交友wordpressseo排名哪家正规
  • 电商网站开发语言抖音营销推广方案
  • 婚恋网站制作要多少钱最牛餐饮营销手段
  • 网站被301好的网络推广平台
  • 宝鸡外贸网站建设百度联系方式
  • 做seo网站seo站外推广有哪些
  • 网站新闻页面无法翻页网站外包公司有哪些
  • 专业做羽绒服的服装网站百度云网盘免费资源
  • 网站建设仟首先金手指13企业网站的主要类型有