Go language Implementation RPC

Source: Internet
Author: User
Tags get ip

RPC definition, from Baidu Encyclopedia

    • RPC (remote Procedure Call)-an agreement that requests a service from a remote computer program over a network without needing to know the underlying network technology. The RPC protocol assumes that some transport protocols exist, such as TCP or UDP, to carry information data between communication programs. In the OSI network communication model, RPC spans the transport and application tiers. RPC makes it easier to develop applications that include distributed, multi-program networks.

    • RPC takes client/server mode. The requestor is a client, and the service provider is a server. First, the client call process sends a call message with process parameters to the service process, and then waits for the reply message. On the server side, the process stays asleep until the call information arrives. When a call arrives, the server obtains the process parameters, evaluates the result, sends a reply message, and then waits for the next invocation information, and finally, the client invokes the process to receive the reply message, obtains the process result, and then invokes execution to proceed.

    • There are multiple RPC modes and executions. Originally presented by Sun Corporation. The IETF ONC charter re-revised the Sun version, making the ONC RPC protocol an IETF standard protocol. Now using the most common patterns and execution is an open software-based distributed computing Environment (DCE).

    • Personal understanding: Do not care what the underlying network technology protocol, is a network from the computer program to request services, popular point, we write code, in a place, such as Android, you need to be in a project inside, can call to other program code execution process. The Go language provides RPC support to enable applications that develop network-distributed programs toeasy

RPC Workflow Flowchart

Images from GitHub
    • 1. Invoking the client handle; executing the transfer parameters
    • 2. Call the local system kernel to send a network message
    • 3. Messaging to a remote host
    • 4. Server handle get message and get parameters
    • 5. Performing a remote procedure
    • 6. The execution process returns the result to the server handle
    • 7. Server handle returns result, call remote system kernel
    • 8. Send the message back to the local host
    • 9. Client handles receive messages from the kernel
    • 10. The customer receives the data returned by the handle

The Go language provides support for RPC: HTTP、TCP、JSPNRPC but Go RPC it is unique in that it uses GoLang Gob encoding and can only support the go language!

    • Golang Gob: is a data structure serialized encoding/decoding tool with Golang package. Encoding uses encoder, decoding uses decoder. A typical application scenario is RPC (remote procedure calls).

HTTP RPC Demo

    • Service-side code
Package Mainimport ("FMT" "Net/rpc" "Net/http" "errors") func main () {Rpcdemo ()}type arith intfunc Rpcdem O () {arith:=new (arith)//arith=== 0xc04204e090 FMT. Println ("arith===", Arith) RPC.    Register (Arith)//handlehttp the HTTP handler for the RPC message to the debug handler on the Debug server//defautupcpath and debug debug path. HTTP still needs to be called.    Services (), usually in a go statement. Rpc. Handlehttp () err:=http. Listenandserve (": 1234", nil) if err! = Nil {fmt. Println ("err=====", err. Error ())}}type Args struct {A, B int}type quotient struct {Quo, Rem int}//function must be exported (capitalized)//must have two parameters for export type,//First parameter  The number is the received parameter, the second parameter is the parameter returned to the client, the second argument must be a pointer type//function and a return value of Errorfunc (t *arith) Multiply (args *args, reply *int) error {*reply = Args. A * args. FMT B. Println ("This method executes AH---hehe---Multiply", reply) return Nil}func (t *arith) Divide (args *args, quo *quotient) error {if Args. B = = 0 {return errors. New ("Divide by Zero")} quo. Quo = args. A/args. B Quo. Rem = args. A% args. FMT B. Println ("This method has been executed---Hehe---Divide quo== ", quo) return nil} 
    • The function of Go RPC can be accessed remotely only if it meets four criteria, otherwise it will be ignored
      • The function must be capitalized (can be exported)
      • Must have two parameters for the exported type
      • The first parameter is the accepted argument, the second argument is the parameter returned to the client, and the second argument is the type of the pointer
      • Function must also have a return valueerror
func (t *T) MethodName(argType T1, replyType *T2) error
    • The T, T1, and T2 types must be capable of being decoded by the encoding/gob package.

    • The client's code

Package Mainimport ("Log" "FMT" "OS" "Net/rpc" "StrConv") type argstwo struct {A, B int}type QUOTIENTTW o struct {Quo, Rem Int}func Main () {//If nothing is entered, it is the following value//os***************** [C:\Users\win7\AppData\Local\ temp\go-build669605574\command-//line-arguments\_obj\exe\gorpcweb.exe 127.0.0.1] ********************** fmt. Println ("os*****************", OS. Args, "**********************") If Len (OS. Args)! = 4 {//TODO the second address is our local address FMT. Println ("Lao Tzu to Quit Oh, the first start--------" ", OS.) Args[0], "---------------server End") OS. Exit (1)}else{FMT. Println ("Length is how much" +strconv. Itoa (len (OS). Args) + "is the exact length oh---")}//Gets the input address is the value of the first location to get input OS data serveraddress: = OS. ARGS[1] FMT.    Println ("severaddress==", serveraddress)////delayhttp is connected to the HTTP RPC server at the specified network address///listening on the default HTTP RPC path. Client, err: = RPC. Dialhttp ("TCP", serveraddress) if err! = Nil {log. Fatal ("Error has occurred here in place Dialhttp", err)} i1,_:=strconv. Atoi(OS. ARGS[2]) I2,_:=strconv. Atoi (OS.    Args[3]) Args: = Argstwo{i1, i2} var reply int//Call Call the named function, wait for it to complete, and return its error state. Err = client. Call ("Arith.multiply", args, &reply) if err! = Nil {log. Fatal ("Call Multiply error has occurred oh Arith error:", err)} FMT. Printf ("Arith multiplication:%d*%d=%d\n", args. A, args.    B, Reply) var quot quotienttwo//Call the named function, wait for it to complete, and return its error state. Err = client. Call ("Arith.divide", args, &quot) if err! = Nil {log. Fatal ("Arith error:", err)} FMT. Printf ("Arith Division takes integers:%d/%d=%d remainder%d\n", args. A, args. B, quot. Quo, quot. REM)}
Run a result diagram
E:\new_code\GoDemo\web_server>go run GoRPCWeb8.go 127.0.0.1:1234  20 3os***************** [C:\Users\win7\AppData\Local\Temp\go-build011170718\command-line-arguments\_obj\exe\GoRPCWeb8.exe 127.0.0.1:1234 20 3] **********************长度是多少 4才是准确的长度 哦---》severAddress== 127.0.0.1:1234Arith 乘法: 20*3=60Arith 除法取整数: 20/3=6 余数 2
    • Go run gorpcweb8.go 127.0.0.1:1234 20 3
      • Commands run by Go run
      • Gorpcweb8.go: This is the name of the file and needs to be started in the specified directorycmd
      • 127.0.0.1:1234:IP Address and port number
      • 20 3 This is the customer service. The value passed in: a divisor, a divisor, incoming to the server multiplication multiplication: 20*3=60 and division take integer: 20/3=6 remainder 2 , how to do, the client does not care, to the service side to complete
    • os.Args[0]=[C:\Users\win7\AppData\Local\Temp\go-build011170718\command- line-arguments\_obj\exe\GoRPCWeb8.exe 127.0.0.1:1234 20 3]
    if len(os.Args) != 4 { //   todo  第二个地址是  我们本地的地址        fmt.Println("老子要退出了哦 傻逼 一号start--------》》》", os.Args[0], "《《《---------------server  end")        os.Exit(1)    }else{        fmt.Println("长度是多少 "+strconv.Itoa( len(os.Args))+"才是准确的长度 哦---》")    }

TCP RPC Demo

    • RPC, server-side code implementation based on TCP protocol
Package Mainimport ("FMT" "Net/rpc" "NET" "OS" "Errors") Func init () {FMT. Println ("RPC based on TCP protocol, service-side code is as follows")}type Me struct {A, b int}type you struct {cc,d int}type Num int/*go RPC function only conforms to the following The condition can be accessed remotely, otherwise it will be ignored 1 function must be exported (first letter uppercase) 2 must have two export type parameter 3 The first parameter is an accepted parameter, the second parameter is the parameter returned to the client, the second argument must be of type 4 function must also have a return value error */ Func (n *num) M (args *me,reply *int) error {*reply=args. A * args. B return Nil}func (n *num) F (args * me,u *you) error {if args. b==0{return errors. New ("Input cannot be 0 dividend")} U.d=args. A/args. B U.cc=args. A% args. B return Nil}func Main () {///the built-in function new is essentially the same as the function of the same name in other languages: new (T) allocates a memory space of type T with a value of 0, and returns its address, which is the value of a *t type. In the terms of go, it returns a pointer to the 0 value of the newly assigned type T.    One thing is very important://new returns a pointer. Num:=new (Num) RPC.    Register (num)//resolvetcpaddr returns the address of the TCP endpoint.    The network must be a TCP network name. Tcpaddr,err:=net. RESOLVETCPADDR ("TCP", ": 1234") if err! = Nil {fmt. Println ("Wrong Oh") os. Exit (1)} listener,err:=net. LISTENTCP ("TCP", tcpaddr) for {//TODO requiredTo control the connection yourself, we need to give the connection to RPC to handle the Conn,err:=listener when there is a client connection. Accept () if err! = nil {continue} RPC. SERVECONN (conn)}}
    • based on TCP client code
Package Mainimport ("FMT" "OS" "Net/rpc" "Log" "StrConv") func main () {FMT. Println ("The other side of the client to call where the corresponding example is Gotcprpc9.go") If Len (OS. Args) ==4{FMT. PRINTLN ("Length must be equal to 4, because what you enter is definitely an IP address ip=", OS. Args[1], "hehe, plus the back of the dividend OS. Args[2]= ", Os. ARGS[2], "and the divisor OS. Args[3]= ", Os. ARGS[3])//os. Exit (1)}//Get IP address service:= os.    ARGS[1]//Connect a dial-up connection to the specified network address of the RPC server. Client,err:=rpc. Dial ("TCP", service) if Err!=nil {log. Fatal ("I am in connection with dial error, I want to quit", err)} num1:=os. ARGS[2] I1,error1:=strconv. Atoi (NUM1) if Error1!=nil {fmt. Println ("I don't know if I entered the wrong one, see error:", Error1) os. Exit (1)} num2:=os. ARGS[3] I2,error2:=strconv. Atoi (num2) if Error2!=nil {fmt. Println ("I don't know if I entered the wrong one, see error:", Error2) os. Exit (1)} Aa:=aaa{i1,i2} var reply int err1:=client. Call ("NUM.M", aa,&reply) if err1! = nil{log. Fatal ("I'm quitting because I had an error at call", ERR1)} fmt. PRINTLN ("I conduct normal results as follows") FMT. Printf ("Num:%d*%d=%d\n ", AA. A,aa.    b,reply) var bb bdemo//calls the named function, waits for it to complete, and returns its error state. Err= client. Call ("NUM.F", AA,&BB) if Err!=nil {log. Fatal ("I reacted to this method of allergic reaction haha haha err=====", err)} FMT. Printf ("Num:%d/%d=%d remainder%d\n", AA. A,aa. B,bb. Dd,bb. CC)}//defines two classes, where the class that needs to be manipulated type AAA struct {A, B int}//remember there is no way to capitalize a two-letter together capitalization a little meaning//reading body gob:type mismatch:no Field  s matched compiling decoder for dddd//todo Why the second parameter as long as it is two connected DDDD will be an error reading body Gob:type mismatch:no fields Matched compiling decoder fortype bdemo struct {DD, CC int}
    • Run the result diagram


      Result diagram
E:\new_code\GoDemo\web_server>go run GoTCPRPCWeb10.go 127.0.0.1:1234  20 1客户端 其他端 去调用的地方  对应的例子是 GoTCPRPC9.go长度必须等于4,因为呢,你输入的肯定是一个ip的地址ip= 127.0.0.1:1234 嘿嘿,加上后面的被除数os.Args[2]= 20 和除数os.Args[3]= 1我进行正常结果如下Num : 20*1=20Num: 20/1=0 余数 0E:\new_code\GoDemo\web_server>go run GoTCPRPCWeb10.go 127.0.0.1:1234  20 2客户端 其他端 去调用的地方  对应的例子是 GoTCPRPC9.go长度必须等于4,因为呢,你输入的肯定是一个ip的地址ip= 127.0.0.1:1234 嘿嘿,加上后面的被除数os.Args[2]= 20 和除数os.Args[3]= 2我进行正常结果如下Num : 20*2=40Num: 20/2=0 余数 0E:\new_code\GoDemo\web_server>go run GoTCPRPCWeb10.go 127.0.0.1:1234  20 3客户端 其他端 去调用的地方  对应的例子是 GoTCPRPC9.go长度必须等于4,因为呢,你输入的肯定是一个ip的地址ip= 127.0.0.1:1234 嘿嘿,加上后面的被除数os.Args[2]= 20 和除数os.Args[3]= 3我进行正常结果如下Num : 20*3=60Num: 20/3=0 余数 2
    • At the BDemo time of definition, if the definition DD, CC int and the service side is not the same, will be error reading body gob: type mismatch: no fields matched compiling decoder for , in fact, found a good variety of situations, will also appear this error, but at present do not know why this, follow-up, such as the source into a bit, come back to see this problem TODO2018/07/19
    • The TCP difference between this way and the above HTTP is that
      • http: Specifies the network address to connect to the HTTP RPC server
         //DelayHTTP在指定的网络地址连接到HTTP RPC服务器    ///在默认HTTP RPC路径上监听。    client, err := rpc.DialHTTP("tcp", serverAddress)
    • TCP: Specifies the network address to connect to the HTTP RPC server
    client,err:=rpc.Dial("tcp",service)

JSON RPC

    • JSON RPCIs that the data is encoded using JSON , rather than gob coding, the others are identical to the concepts described above RPC .

    • The service-side code is as follows

package mainimport (    "fmt"    "net/rpc"    "net"    "net/rpc/jsonrpc")//使用Go提供的json-rpc 标准包func init() {    fmt.Println("JSON RPC 采用了JSON,而不是 gob编码,和RPC概念一模一样,")}type Work struct {    Who,DoWhat string}type DemoM stringfunc (m *DemoM) DoWork(w *Work,whoT *string) error  {    *whoT="是谁:"+w.Who+",在做什么---"+w.DoWhat    return nil}func main() {    str:=new(DemoM)    rpc.Register(str)    tcpAddr,err:=net.ResolveTCPAddr("tcp",":8080")    if  err!=nil{        fmt.Println("大哥发生错误了啊,请看错误 ResolveTCPAddr err=",err)    }    listener,err:=net.ListenTCP("tcp",tcpAddr)    if err!=nil {        fmt.Println("发生错误了--》err=",err)    }    for  {         conn,err:= listener.Accept()        if err!=nil {            continue        }        jsonrpc.ServeConn(conn)    }}
    • The client's code
package mainimport (    "fmt"    "os"    "net/rpc/jsonrpc"    "log")func main() {    fmt.Println("这是客户端,用来启动,通过命令行来启动")    fmt.Println("客户端 其他端 去调用的地方  对应的例子是 GoTCPRPC9.go")    if len(os.Args)==4{        fmt.Println("长度必须等于4,因为呢,你输入的肯定是一个ip的地址ip=",os.Args[1],"嘿嘿,加上后面的被除数os.Args[2]=",os.Args[2],"和除数os.Args[3]=",os.Args[3])        //os.Exit(1)    }     service:=os.Args[1]     client,err:=jsonrpc.Dial("tcp",service)    if err != nil {        log.Fatal("Dial 发生了错误了哦 错误的信息为   err=",err)    }    send:=Send{os.Args[2],os.Args[3]}    var  resive  string    err1:=client.Call("DemoM.DoWork",send,&resive)    if err1!=nil {        fmt.Println("shiming call error    ")        fmt.Println("Call 的时候发生了错误了哦  err=",err1)    }    fmt.Println("收到信息了",resive)}// 类可以不一样 但是 Who 和DoWhat 要必须一样  要不然接收到不到值,等我在详细的了解了 才去分析下原因  感觉有点蒙蔽啊type Send struct {    Who, DoWhat string}
    • The results of the operation are as follows


      Run results
E:\new_code\GoDemo\web_server>go run GoJSONRPCWeb11.go 127.0.0.1:8080  shiming gongzuo这是客户端,用来启动,通过命令行来启动客户端 其他端 去调用的地方  对应的例子是 GoTCPRPC9.go长度必须等于4,因为呢,你输入的肯定是一个ip的地址ip= 127.0.0.1:8080 嘿嘿,加上后面的被除数os.Args[2]= shiming 和除数os.Args[3]= gongzuo收到信息了 是谁:shiming,在做什么---gongzuoE:\new_code\GoDemo\web_server>go run GoJSONRPCWeb11.go 127.0.0.1:8080  shiming qiaodaima这是客户端,用来启动,通过命令行来启动客户端 其他端 去调用的地方  对应的例子是 GoTCPRPC9.go长度必须等于4,因为呢,你输入的肯定是一个ip的地址ip= 127.0.0.1:8080 嘿嘿,加上后面的被除数os.Args[2]= shiming 和除数os.Args[3]= qiaodaima收到信息了 是谁:shiming,在做什么---qiaodaima
    • os.Argsis an array var Args []string , obtained through input, and then the content of the client input to the server, the server to do some operations, and then return to the client
    • Gohas provided a RPC good support, through HTTP TCP JSONRPC the implementation, can be very convenient to develop distributed Web applications, but I do not, in the study. Unfortunately there is Go no SOAP RPC support provided ~ ~ ~
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.