当前位置:网站首页>Go language RPC communication

Go language RPC communication

2022-04-23 16:55:00 The interview was rejected 10000 times

RPC Call the procedure remotely ,

 Procedure for calling other services , Middle note is a common communication method for calling different nodes in distributed system. 

RPC The of service interface is divided into three parts

  1. The name of the service
    To avoid package name conflicts , We can register the service Add the path of the package , This path is not go Execution path of ,
    rpc.RegisterName() The function is registered , The compiler will require that the passed in match Function of service interface ,

       const HelloServiceNmae = "/path/to/pkg.HelloService"  //  Add the name of the package when registering 
       type HelloServiceInterface = interface {
          
          hello( requst string,replace *string ) error   //  Declaration of functions 
       }
    
    
  2. Detailed method list to be implemented by the service

    Function in service correspondence method ,hello function

    • Method has two serializable parameters , The second parameter is the pointer type , Return to one error type
          Hello(request string, reply *string) error
    
    • The method has to be public , Which starts with capital letters
  3. Register functions for this service type

    • According to the service name or path name , Sign up for service to RPC
      //  Register function 
      func RegisterHelloService(src HelloServiceInterface) error {
          
          return rpc.RegisterName(HelloServiceNmae,src)
      }
    
    • When the client calls , It will also call according to the specification RPC Functions registered in
    func (p *HelloServiceClient) Hello(request string, repley *string) error {
          
    //  call RPC Your service name   and   Method , Pass in the address of the return parameter 
    return p.Client.Call(service.HelloServiceName+".Hello", request, repley)
    }
    

demo

  • Based on hello Interface /RPC/service/HelloService.go
package service

const HelloServiceName = "HelloService"

type HelloService interface {
    
	Hello(request string, reply *string) error
}

  • Server side /RPC/server/main.go
package main

import (
"gowork/RPC/service"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
)

type HelloService struct {
    

}
// constraint   Server side 
var _ service.HelloService = (*HelloService)(nil)

func (p *HelloService) Hello(request string, reply *string) error {
    
    *reply = "hello -" + request
    return nil
}

func main() {
    
    //  Register the object as a rpc Of  recevier
    //  among Rpc.Register  The function will all objects in the object type that meet RPC Object method of rule   register as RPC function 
    //  All registered functions will be placed in  HelloService  In this space 
    rpc.RegisterName(service.HelloServiceName, new(HelloService))

    //  Build a TCP  Connect 
    lissenter, err := net.Listen("tcp", ":1234")
    if err != nil {
    
      log.Fatal("Tcp listen is error", err)
    }

    //  adopt rpc.ServeConn Function in this TCP Link to provide RPC service .
    //  Every time Accept A request , Just create one goroutie To deal with 
    for {
    
      connect, err := lissenter.Accept()
      if err != nil {
    
        log.Fatal(" Tcp Accept error")
      }

      //  For each  TCP  Provide... For clients rpc  service 
      go rpc.ServeCodec(jsonrpc.NewServerCodec(connect))
    }
}

  1. RPC Packages are built on net Upper , At every TCP Provide services after linking
  2. Meet the requirements of RPC The method of rules , This RPC The rules There are two main points :
    • Method has two serializable parameters , The second parameter is the pointer type , Return to one error type
        	Hello(request string, reply *string) error
    
    • The method has to be public , Which starts with capital letters
  3. The methods of successful registration are put in , Register in the service name space , In the use of RPC When calling a method , Use the service name + Method
  • client /RPC/client/main.go
package main

import (
	"fmt"
	"gowork/RPC/service"
	"log"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
)

type HelloServiceClient struct {
    
	*rpc.Client
}

//  Constraint client 
//  New addition  HelloServiceClient  type , however   The new type must meet  service.HelloService  Interface type 
//  To put it simply  HelloServiceClient  Follow  HelloService  The same type , The functions in the two interfaces are consistent   The functions are the same 
var _ service.HelloService = (*HelloServiceClient)(nil)

//RPC  Dial up service , Connect to server 
func DialHelloService(network, adress string) (*HelloServiceClient, error) {
    
	connect, err := net.Dial(network, adress)
	if err != nil {
    
		log.Fatal("net dial is error")
	}
	//  use json Coding client 
	c := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(connect))
	return &HelloServiceClient{
    Client: c}, nil
}

func (p *HelloServiceClient) Hello(request string, repley *string) error {
    
	//  call RPC Your service name   and   Method , Pass in the address of the return parameter 
	return p.Client.Call(service.HelloServiceName+".Hello", request, repley)
}
func main() {
    

	client, err := DialHelloService("tcp", "localhost:1234")
	if err != nil {
    
		log.Fatal("dialting ")
	}

	var reply string
	err = client.Hello("world", &reply)
	if err != nil {
    
		log.Fatal(" client hello error ", err)
	}
	fmt.Println("reply ", reply)
}

  1. call RPC Methods , First, dial up the connection ,net.Dial
  2. Call specific RPC When it comes to methods , Use RPC.Call() Pass in the service name , Request parameters , Returns the parameter
  • test

Start the server

cd /RPC/server/main.go
go run main.go

Start client :

cd /RPC/client/main.go
go run main.go

result :

reply hello -world

Cross language RPC signal communication

golang The coding method provided gob, Use other languages and go When communicating , You can choose common coding methods

  • MessagePack: Efficient binary serialization format . It allows multiple languages ( Such as JSON) Data exchange between . But it's faster and smaller
  • JSON: Text encoding
  • XML: Text encoding
  • Protobuf Binary code
RPC stay go Characteristics in :
  1. yes RPC data When packaging, you can implement custom encoding and decoding through plug-ins ;
  2. Based on abstract io.ReadWriteCloser On the interface , We can RPC Built on different communication protocols
be based on json The code is reimplemented RPC service

server.go( Server side ) :

 go  rpc.ServeCodec(jsonrpc.NewServerCodec(conn))
 //  The parameters passed in are for the server json  codecs .

client.go( client ) :

  client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
   Establish a pin based on this link   On the client side json codecs .

In the access to RPC Call corresponding json After the data , We can go straight to the rack Yes RPC Service TCP Server send json The data simulation RPC Method call :

echo -e ‘{“method”:“HelloService.Hello”,“params”:[“hello”],“id”:1}’ | nc localhost 1234

Simulate client sending rpc call

  • method Is the name of the called service
  • params Pass in the parameter
  • id A unique call number maintained by the caller

Return results :

{ “id” : 1 , “result” : “hello:hello” , “error” : null }

This Reading Note , read 《GO Language advanced programming 》 income ,

版权声明
本文为[The interview was rejected 10000 times]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231359046217.html