...

Package rpc

import "net/rpc"
概览
索引
子目录

概览 ▾

rpc 包提供了一个方法来通过网络或者其他的I/O连接进入对象的外部方法. 一个server注册一个对象, 标记它成为可见对象类型名字的服务。注册后,对象的外部方法就可以远程调用了。一个server可以注册多个 不同类型的对象,但是却不可以注册多个相同类型的对象。

只有满足这些标准的方法才会被远程调用视为可见;其他的方法都会被忽略:

- 方法是外部可见的。
- 方法有两个参数,参数的类型都是外部可见的。
- 方法的第二个参数是一个指针。
- 方法有返回类型错误

事实上,方法必须看起来类似这样

func (t *T) MethodName(argType T1, replyType *T2) error

T,T1和T2可以被encoding/gob序列化。 不管使用什么编解码,这些要求都要满足。 (在未来,这些要求可能对自定义的编解码会放宽)

方法的第一个参数代表调用者提供的参数;第二个参数代表返回给调用者的参数。方法的返回值,如果是非空的话 就会被作为一个string返回,客户端会error像是被errors.New调用返回的一样。如果error返回的话, 返回的参数将会被送回给客户端。

服务断可以使用ServeConn来处理单个连接上的请求。更通用的方法,服务器可以制造一个网络监听,然后调用 Accept,或者对一个HTTP监听,处理HandleHTTP和http.Serve。

客户端希望使用服务来建立连接,然后在连接上调用NewClient来建立连接。更方便的方法就是调用Dial(DialHTTP) 来建立一个新的网络连接(一个HTTP连接)。客户端获得到的对象有两个方法,Call和Go,指定的参数有:服务和方法 指向参数的指针,接受返回结果的指针。

call方法等待远程调用完成,但Go方法是异步调用call方法,使用Call通道来标志调用完成。

除非有明确制定编解码器,否则默认使用encoding/gob来传输数据。

这是个简单的例子,服务器希望对外服务出Arith对象:

package server

type Args struct {
	A, B int
}

type Quotient struct {
	Quo, Rem int
}

type Arith int

func (t *Arith) Multiply(args *Args, reply *int) error {
	*reply = args.A * args.B
	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.B
	return nil
}

服务端调用(使用HTTP服务):

arith := new(Arith)
rpc.Register(arith)
rpc.HandleHTTP()
l, e := net.Listen("tcp", ":1234")
if e != nil {
	log.Fatal("listen error:", e)
}
go http.Serve(l, nil)

在这个时候,客户端可以看见服务“Arith”,并且有“Arith.Multiply”方法和“Arith.Divide”方法。 调用其中一个,客户端首先连接服务:

client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
if err != nil {
	log.Fatal("dialing:", err)
}

当它要调用远程服务的时候:

// Synchronous call
args := &server.Args{7,8}
var reply int
err = client.Call("Arith.Multiply", args, &reply)
if err != nil {
	log.Fatal("arith error:", err)
}
fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)

or

// Asynchronous call
quotient := new(Quotient)
divCall := client.Go("Arith.Divide", args, quotient, nil)
replyCall := <-divCall.Done	// will be equal to divCall
// check errors, print, etc.

服务端的实现需要为客户端提供一个简单的,类型安全服务。

索引 ▾

常量
变量
func Accept(lis net.Listener)
func HandleHTTP()
func Register(rcvr interface{}) error
func RegisterName(name string, rcvr interface{}) error
func ServeCodec(codec ServerCodec)
func ServeConn(conn io.ReadWriteCloser)
func ServeRequest(codec ServerCodec) error
type Call
type Client
    func Dial(network, address string) (*Client, error)
    func DialHTTP(network, address string) (*Client, error)
    func DialHTTPPath(network, address, path string) (*Client, error)
    func NewClient(conn io.ReadWriteCloser) *Client
    func NewClientWithCodec(codec ClientCodec) *Client
    func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error
    func (client *Client) Close() error
    func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call
type ClientCodec
type Request
type Response
type Server
    func NewServer() *Server
    func (server *Server) Accept(lis net.Listener)
    func (server *Server) HandleHTTP(rpcPath, debugPath string)
    func (server *Server) Register(rcvr interface{}) error
    func (server *Server) RegisterName(name string, rcvr interface{}) error
    func (server *Server) ServeCodec(codec ServerCodec)
    func (server *Server) ServeConn(conn io.ReadWriteCloser)
    func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)
    func (server *Server) ServeRequest(codec ServerCodec) error
type ServerCodec
type ServerError
    func (e ServerError) Error() string

包文件

client.go debug.go server.go

常量

const (
    // Defaults used by HandleHTTP  //默认被HandleHTPP使用
    DefaultRPCPath   = "/_goRPC_"
    DefaultDebugPath = "/debug/rpc"
)

变量

var DefaultServer = NewServer()

DefaultServer是默认的*Server实例。

var ErrShutdown = errors.New("connection is shut down")

func Accept

func Accept(lis net.Listener)

Accept在连接上监听和服务请求,为每个连接调用DefaultServer。 Accept是阻塞的,调用者一般是在go语句中调用。

func HandleHTTP

func HandleHTTP()

HandleHTTP在DefaultRPCPath上为RPC消息注册了一个HTTP的处理器到DefaultServer上,并且在 DefaultDebugPath上注册了一个debuggin处理器。 它仍然需要调用http.Serve(),一般是在go语句中。

func Register

func Register(rcvr interface{}) error

Register在DefaultServer中发布接收者的方法

func RegisterName

func RegisterName(name string, rcvr interface{}) error

RegisterName就像Register,但是为类型使用自定义的名字而不是接收者定义的名字。

func ServeCodec

func ServeCodec(codec ServerCodec)

ServeCodec和ServeConn一样,但是使用特定的codec来解码请求,编码回复。

func ServeConn

func ServeConn(conn io.ReadWriteCloser)

ServeConn在单个连接上调用DefaultServer。 ServeConn阻塞,服务连接,直到客户端关闭。 调用者一般在go语句中调用ServeConn。ServeConn在连接上使用gob格式(参考gob包)。 要使用自定义的编解码,使用ServeCodec.

func ServeRequest

func ServeRequest(codec ServerCodec) error

ServeRequest和ServeCodec相似,但是同步地服务单个请求。 它直到完成了才关闭codec。

type Call

type Call struct {
    ServiceMethod string      // The name of the service and method to call.  // 要调用的服务名字和方法
    Args          interface{} // The argument to the function (*struct).  // 方法的参数(*struct)
    Reply         interface{} // The reply from the function (*struct).  // 方法的返回值(*struct)
    Error         error       // After completion, the error status.  // 完成之后返回的error
    Done          chan *Call  // Strobes when call is complete.  // 调用完成的信号
}

Call 代表一个活跃的RPC

type Client

type Client struct {
    // contains filtered or unexported fields
}

Client代表一个RPC客户端。 一个客户端可以有多个调用,并且一个客户端可以被多个goroutine同时使用

func Dial

func Dial(network, address string) (*Client, error)

Dial根据指定的网络地址连接到一个RPC服务。

func DialHTTP

func DialHTTP(network, address string) (*Client, error)

DialHttp根据制定的网络地址,连接到一个HTTP RPC服务。并且在默认的HTTP RPC路径进行监听。

func DialHTTPPath

func DialHTTPPath(network, address, path string) (*Client, error)

DialHTTPPATH根据制定的网络地址和路径连接到一个HTTP RPC服务。

func NewClient

func NewClient(conn io.ReadWriteCloser) *Client

NewClient returns a new Client to handle requests to the set of services at the other end of the connection. It adds a buffer to the write side of the connection so the header and payload are sent as a unit.

func NewClientWithCodec

func NewClientWithCodec(codec ClientCodec) *Client

NewClientWithCodec is like NewClient but uses the specified codec to encode requests and decode responses.

func (*Client) Call

func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error

Call调用方法的名字,等待它完成,然后返回成功或失败的error状态。

func (*Client) Close

func (client *Client) Close() error

func (*Client) Go

func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call

Go能异步调用功能。它返回Call结构来代表回调。当调用完成,返回相同的Call对象,done channel就会获取到 信息。如果done是空的话,Go就会分配一个新的channel。如果非空的话,done必须缓冲起来,或者Go会立即崩溃。

type ClientCodec

type ClientCodec interface {
    // WriteRequest must be safe for concurrent use by multiple goroutines.
    WriteRequest(*Request, interface{}) error
    ReadResponseHeader(*Response) error
    ReadResponseBody(interface{}) error

    Close() error
}

ClientCodec实现了客户端一方对RPC会话的写RPC请求,和读RPC回复功能。客户端调用WriterRequest 往连接中写RPC请求,同时调用ReadResponseHeader和ReadResponseBody来读取RPC返回。当结束连接的时候 客户端调用Close。ReadResponseBody可以使用一个nil参数,来读取RPC回复,然后丢弃信息。

type Request

type Request struct {
    ServiceMethod string // format: "Service.Method"  // 格式:“Service.Method”
    Seq           uint64 // sequence number chosen by client  // 客户端序列化的数
    // contains filtered or unexported fields
}

Request是在每个RPC调用之前使用的header。它是内部使用的,写在这里是为了调试用,例如分析网络的流量等。

type Response

type Response struct {
    ServiceMethod string // echoes that of the Request  // 每个Request的相应方法
    Seq           uint64 // echoes that of the request  // 每个request的相应
    Error         string // error, if any.  // 如果有的话,表示错误
    // contains filtered or unexported fields
}

Response是在每个RPC回复之前被写在头里面的。它是内部使用的,写在这里是为了调试用,例如分析网络的流量等。

type Server

type Server struct {
    // contains filtered or unexported fields
}

Server代表一个RPC服务。

func NewServer

func NewServer() *Server

NewServer返回一个新的Server

func (*Server) Accept

func (server *Server) Accept(lis net.Listener)

Accept接收连接,为每个连接监听和服务请求。Accept是阻塞的,调用者一般在go语句中使用它。

func (*Server) HandleHTTP

func (server *Server) HandleHTTP(rpcPath, debugPath string)

HandleHTTP在rpcPath上为RPC消息注册一个HTTP处理器,并在debugPath注册一个debugging处理器。 它仍然需要调用http.Serve(),一般是在go语句中使用。

func (*Server) Register

func (server *Server) Register(rcvr interface{}) error

Register发布服务器的一系列方法,接受器必须满足这几个条件:

- 对外可见的方法
- 两个参数,都指向对外可见的结构
- 一个error类型返回值

如果接收者不是一个对外可见的类型,或者没有任何方法,或者没有满足条件的方法,都会返回error。 它也会使用log包来记录错误。客户端进入每个方法使用字符串格式形如“Type.Method”, 这里Type是接收者的具体的类型。

func (*Server) RegisterName

func (server *Server) RegisterName(name string, rcvr interface{}) error

RegisterName像Register,但是为type使用提供的名字,而不是使用receivers的具体类型。

func (*Server) ServeCodec

func (server *Server) ServeCodec(codec ServerCodec)

ServerCodec和ServeConn相似,但是使用自定义的编解码器来解码请求和编码回复。

func (*Server) ServeConn

func (server *Server) ServeConn(conn io.ReadWriteCloser)

ServeConn在单个连接上跑server。 ServeConn阻塞,知道客户端关闭之后才继续服务其他连接。 调用者一般在go语句中调用ServeConn。 ServeConn在连接传输的时候使用gob格式(参考gob包)。可以使用自定义编码器,ServeCodec。

func (*Server) ServeHTTP

func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP实现了http.Handler,并且回复RPC请求。

func (*Server) ServeRequest

func (server *Server) ServeRequest(codec ServerCodec) error

ServerRequest和ServeCodec相似,但是是同步地服务单个请求。 它在结束的时候不会关闭编解码器。

type ServerCodec

type ServerCodec interface {
    ReadRequestHeader(*Request) error
    ReadRequestBody(interface{}) error
    // WriteResponse must be safe for concurrent use by multiple goroutines.
    WriteResponse(*Response, interface{}) error

    Close() error
}

ServerCodec实现了为RPC会话提供读RPC请求和写PRC回复的服务端的方法。服务端调用 ReadRequestHeader和ReadRequestBody来读取连接上的请求,然后调用WriteResponse来 写回复。服务端当结束连接的时候调用Close。ReadRequestBody可能会调用一个nil参数来强迫 读取请求内容并忽略。

type ServerError

type ServerError string

ServerError 代表从远程RPC连接另一端返回的错误

func (ServerError) Error

func (e ServerError) Error() string

子目录

名称      摘要
..
jsonrpc      jsonrpc 包使用了rpc的包实现了一个JSON-RPC的客户端解码器和服务端的解码器.