golang RPC 应用(1) :netrpc的应用

golang RPC 应用(1) :netrpc的应用,第1张

概述RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。---百度百科 实际后台开发中,rpc是服务器与服务器交互的方式之

RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。---百度百科
实际后台开发中,rpc是服务器与服务器交互的方式之一,隐藏底层网络实现,代码程式化,开发效率高,BUG少。

通过一个简单的demo来说明go官方rpc包的应用。
项目结构:

rpc    ----Makefile    ----src        ----clIEnt            ----main.go        ----protocol            ----type.go        ----server            ----main.go

rpc/Makefile

GOPATH := $(shell pwd)all:    GOPATH=${GOPATH} go install clIEnt    GOPATH=${GOPATH} go install server

rpc/protocol/type.go

package protocolconst(    RPC_ADDITION = "Calculator.Addition"    RPC_SUBTRACTION = "Calculator.Subtraction"    RPC_MulTIPliCATION = "Calculator.Multiplication"    RPC_divISION = "Calculator.division")type Param struct {    A int32    B int32}

RPC客户端实现,包含同步(Call)和异步(Go)调用方式,通常为了效率会使用异步方式。
rpc/src/clIEnt/main.go

package mainimport "net/rpc"import (    . "protocol"    "fmt"    "time")var (    _CLIENT  *rpc.ClIEnt    _RPC_MSG chan *rpc.Call    _CAN_CANCEL chan bool)func main()  {    DialRpcServer()    //起个协程处理异步rpc调用结果    go loop()    //测试同步的方式调用rpc服务    param := Param{A:int32(10),B:int32(30)}    reply := int32(0)    SynccallrpcFunc(RPC_ADDITION,&param,&reply)    fmt.Printf("Sync Call Addition Result %d \n",reply)    SynccallrpcFunc(RPC_SUBTRACTION,&reply)    fmt.Printf("Sync Call Subtraction Result %d \n",reply)    ////测试异步的方式调用rpc服务    ASynccallrpcFunc(RPC_MulTIPliCATION,&reply)    ASynccallrpcFunc(RPC_divISION,&reply)    //阻塞等待异步调用完成    <- _CAN_CANCEL}func init(){    _RPC_MSG = make(chan *rpc.Call,1024)    _CAN_CANCEL = make(chan bool)}func DialRpcServer(){    c,e := rpc.Dialhttp("tcp","127.0.0.1:2311")    if e != nil {        fmt.Errorf("Dial RPC Error %s",e.Error())    }    _CLIENT = c}//重连RPC服务器func ReDialRpcServer() bool{    c,"127.0.0.1:2311")    if e != nil {        fmt.Printf("ReDial RPC Error %s \n",e.Error())        return false    }    _CLIENT = c    fmt.Println("ReDial Rpc Server Succ")    return true}//同步rpc调用func SynccallrpcFunc(method string,args interface{},reply interface{}){    if nil == _CLIENT{        for{//如果断线就等到重连上为止            if ReDialRpcServer(){                break            }            time.Sleep(5000 * time.Millisecond)        }    }    _CLIENT.Call(method,args,reply)}//异步rpc调用func ASynccallrpcFunc(method string,reply interface{}){    if nil == _CLIENT{        for{//如果断线就等到重连上为止            if ReDialRpcServer(){                break            }            time.Sleep(5000 * time.Millisecond)        }    }    // Go(serviceMethod string,reply interface{},done chan *Call)的done如果填nil会构建个新的channel用于接受结果    _CLIENT.Go(method,reply,_RPC_MSG)}//接收异步调用的返回func loop(){    for{        select {        case rpCMSg,ok := <- _RPC_MSG:            if !ok{                fmt.Errorf("Rpc Call Error")            }            rpCMSgHandler(rpCMSg)        }    }    _CAN_CANCEL <- true}// 处理异步rpc的返回值func rpCMSgHandler(msg * rpc.Call){    switch msg.ServiceMethod {    case RPC_ADDITION:        reply := msg.Reply.(*int32)        fmt.Printf("Addtoion Result [%d] \n",*reply)    case RPC_SUBTRACTION:        reply := msg.Reply.(*int32)        fmt.Printf("Subtraction Result [%d] \n",*reply)    case RPC_MulTIPliCATION:        reply := msg.Reply.(*int32)        fmt.Printf("Multiplication Result [%d] \n",*reply)    case RPC_divISION:        reply := msg.Reply.(*int32)        fmt.Printf("division Result [%d] \n",*reply)    default:        fmt.Errorf("Can Not Handler Reply [%s] \n",msg.ServiceMethod)    }}

RPC服务器的实现。
rpc/src/server/main.go

package mainimport "net/rpc"import (    . "protocol"    "errors"    "net"    "fmt"    "net/http")type Calculator struct {}var (    _DATA *Calculator    _CAN_CANCEL chan bool)func main()  {    runRpcServer()}func init(){    _DATA = new(Calculator)    _CAN_CANCEL = make(chan bool)}func runRpcServer(){    //rpc包里面定义了个DefaultServer,缺省的Register和Handlehttp均是对DefaultServer作的 *** 作,如果想定制新的Server,就自己写    rpc.Register(_DATA)    rpc.Handlehttp()    l,e := net.Listen("tcp","127.0.0.1:2311")    if e != nil{        fmt.Errorf("Create Listener Error %s",e.Error())    }    go http.Serve(l,nil)    //阻塞主进程,等待客户端输入    <-_CAN_CANCEL}//输出方法的格式要求:func (t *T) Methodname(argType T1,replyType *T2) errorfunc (*Calculator) Addition(param *Param,reply *int32) error{    *reply = param.A + param.B    return nil}func (*Calculator) Subtraction(param *Param,reply *int32) error{    *reply = param.A - param.B    return nil}func (*Calculator) Multiplication(param *Param,reply *int32) error{    *reply = param.A * param.B    return nil}func (*Calculator) division(param *Param,reply *int32) error{    if 0 == param.B{        return errors.New("divIDe by zero")    }    *reply = param.A/param.B    return nil}
总结

以上是内存溢出为你收集整理的golang RPC 应用(1) :net/rpc的应用全部内容,希望文章能够帮你解决golang RPC 应用(1) :net/rpc的应用所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1272250.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存