Spec-Zone.ru › Go

Пакет rpc

  • import "net/rpc"
  • Обзор
  • Указатель
  • Подкаталоги

Обзор

Пакет rpc предоставляет доступ к экспортируемым методам объекта по сети или через другое соединение ввода-вывода.

Пакет net/rpc заморожен и новые возможности в него не добавляются.

Сервер регистрирует объект, делая его доступным как службу с именем типа объекта. После регистрации к экспортируемым методам объекта можно будет обращаться удалённо. Сервер может зарегистрировать несколько объектов (служб) разных типов, но регистрация нескольких объектов одного типа приведёт к ошибке.

Для удалённого доступа будут доступны только методы, удовлетворяющие следующим критериям; остальные методы будут проигнорированы:

  • тип метода экспортируемый.
  • метод экспортируемый.
  • у метода два аргумента, оба экспортируемых (или встроенных) типов.
  • второй аргумент метода — указатель.
  • тип возвращаемого значения метода — error.

По сути, метод должен схематично выглядеть так:

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

где T1 и T2 могут быть сериализованы с помощью encoding/gob. Эти требования применяются, даже если используется другой кодек. (В будущем эти требования могут стать менее строгими для пользовательских кодеков.)

Первый аргумент метода представляет аргументы, переданные вызывающей стороной; второй аргумент представляет параметры результата, которые необходимо вернуть вызывающей стороне. Возвращаемое значение метода, если оно не равно nil, передаётся обратно в виде строки, которую клиент видит так, как если бы она была создана с помощью errors.New. Если возвращается ошибка, параметр ответа клиенту не отправляется.

Сервер может обрабатывать запросы по одному соединению, вызывая ServeConn. Чаще сервер создаёт сетевой прослушиватель и вызывает Accept или, для HTTP-прослушивателя, HandleHTTP и http.Serve.

Клиент, желающий воспользоваться службой, устанавливает соединение, а затем вызывает NewClient для этого соединения. Вспомогательная функция Dial (DialHTTP) выполняет оба шага для обычного сетевого соединения (HTTP-соединения). Полученный объект Client имеет два метода — Call и Go, — которым передаются служба и метод для вызова, указатель с аргументами и указатель для получения параметров результата.

Метод Call ожидает завершения удалённого вызова, а метод Go запускает вызов асинхронно и сообщает о завершении через канал Done структуры Call.

Если не задан явный кодек, для передачи данных используется пакет encoding/gob.

Вот простой пример. Сервер хочет экспортировать объект типа Arith:

package server

import "errors"

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, err := net.Listen("tcp", ":1234")
if err != nil {
	log.Fatal("listen error:", err)
}
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)

или

// 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 any) error
  • func RegisterName(name string, rcvr any) 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 any, reply any) error
  • func (client *Client) Close() error
  • func (client *Client) Go(serviceMethod string, args any, reply any, 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 any) error
  • func (server *Server) RegisterName(name string, rcvr any) 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
    DefaultRPCPath   = "/_goRPC_"
    DefaultDebugPath = "/debug/rpc"
)

Переменные

DefaultServer — экземпляр *Server по умолчанию.

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

func Accept

func Accept(lis net.Listener)

Accept принимает соединения от прослушивателя и обрабатывает запросы для DefaultServer по каждому входящему соединению. Accept блокирует выполнение; обычно вызывающая сторона запускает его в операторе go.

func HandleHTTP

func HandleHTTP()

HandleHTTP регистрирует HTTP-обработчик для RPC-сообщений DefaultServer по адресу DefaultRPCPath и обработчик отладки по адресу DefaultDebugPath. По-прежнему необходимо вызвать http.Serve(), обычно в операторе go.

func Register

func Register(rcvr any) error

Register публикует методы получателя в DefaultServer.

func RegisterName

func RegisterName(name string, rcvr any) error

RegisterName действует подобно Register, но использует переданное имя типа вместо конкретного типа получателя.

func ServeCodec

func ServeCodec(codec ServerCodec)

ServeCodec действует подобно ServeConn, но использует указанный кодек для декодирования запросов и кодирования ответов.

func ServeConn

func ServeConn(conn io.ReadWriteCloser)

ServeConn запускает DefaultServer для одного соединения. ServeConn блокируется, обслуживая соединение, пока клиент не отключится. Обычно вызывающий код запускает ServeConn в операторе go. ServeConn использует в соединении формат передачи данных gob (см. пакет gob). Чтобы использовать другую кодировку, используйте ServeCodec. Информацию о параллельном доступе см. в комментарии к NewClient.

func ServeRequest

func ServeRequest(codec ServerCodec) error

ServeRequest подобен ServeCodec, но синхронно обрабатывает один запрос. По завершении он не закрывает кодек.

type Call

Call представляет активный вызов RPC.

type Call struct {
    ServiceMethod string     // The name of the service and method to call.
    Args          any        // The argument to the function (*struct).
    Reply         any        // The reply from the function (*struct).
    Error         error      // After completion, the error status.
    Done          chan *Call // Receives *Call when Go is complete.
}

type Client

Client представляет клиент RPC. С одним Client может быть связано несколько незавершённых вызовов Call, и Client может одновременно использоваться несколькими горутинами.

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

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 возвращает новый Client для обработки запросов к набору служб на другом конце соединения. Он добавляет буфер к стороне записи соединения, чтобы заголовок и полезная нагрузка отправлялись как единое целое.

Части соединения для чтения и записи сериализуются независимо, поэтому синхронизация между ними не требуется. Однако к каждой части может осуществляться параллельный доступ, поэтому реализация conn должна защищать от одновременного чтения или записи.

func NewClientWithCodec

func NewClientWithCodec(codec ClientCodec) *Client

NewClientWithCodec подобен NewClient, но использует указанный кодек для кодирования запросов и декодирования ответов.

func (*Client) Call

func (client *Client) Call(serviceMethod string, args any, reply any) error

Call вызывает функцию с указанным именем, ожидает её завершения и возвращает состояние ошибки.

func (*Client) Close

func (client *Client) Close() error

Close вызывает метод Close базового кодека. Если соединение уже закрывается, возвращается ErrShutdown.

func (*Client) Go

func (client *Client) Go(serviceMethod string, args any, reply any, done chan *Call) *Call

Go асинхронно вызывает функцию. Он возвращает структуру Call, представляющую вызов. Канал done сообщит о завершении вызова, вернув тот же объект Call. Если done равен nil, Go выделит новый канал. Если done не равен nil, он должен быть буферизованным, иначе Go намеренно аварийно завершит работу.

type ClientCodec

ClientCodec реализует запись запросов RPC и чтение ответов RPC на стороне клиента сеанса RPC. Клиент вызывает ClientCodec.WriteRequest, чтобы записать запрос в соединение, а для чтения ответов вызывает попарно ClientCodec.ReadResponseHeader и ClientCodec.ReadResponseBody. По завершении работы с соединением клиент вызывает ClientCodec.Close. Чтобы принудительно прочитать тело ответа и затем отбросить его, ReadResponseBody можно вызвать с аргументом nil. Информацию о параллельном доступе см. в комментарии к NewClient.

type ClientCodec interface {
    WriteRequest(*Request, any) error
    ReadResponseHeader(*Response) error
    ReadResponseBody(any) error

    Close() error
}

type Request

Request — это заголовок, записываемый перед каждым вызовом RPC. Он используется внутри пакета, но описан здесь для упрощения отладки, например при анализе сетевого трафика.

type Request struct {
    ServiceMethod string // format: "Service.Method"
    Seq           uint64 // sequence number chosen by client
    // contains filtered or unexported fields
}

type Response

Response — это заголовок, записываемый перед каждым ответом RPC. Он используется внутри пакета, но описан здесь для упрощения отладки, например при анализе сетевого трафика.

type Response struct {
    ServiceMethod string // echoes that of the Request
    Seq           uint64 // echoes that of the request
    Error         string // error, if any.
    // contains filtered or unexported fields
}

type Server

Server представляет сервер RPC.

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

func NewServer

func NewServer() *Server

NewServer возвращает новый Server.

func (*Server) Accept

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

Accept принимает соединения от прослушивателя и обрабатывает запросы для каждого входящего соединения. Accept блокируется, пока прослушиватель не вернёт ненулевую ошибку. Обычно вызывающий код запускает Accept в операторе go.

func (*Server) HandleHTTP

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

HandleHTTP регистрирует обработчик HTTP для сообщений RPC по пути rpcPath и обработчик отладки по пути debugPath. При этом всё ещё необходимо вызвать http.Serve(), обычно в операторе go.

func (*Server) Register

func (server *Server) Register(rcvr any) error

Register публикует на сервере набор методов значения-получателя, удовлетворяющих следующим условиям:

  • экспортируемый метод экспортируемого типа
  • два аргумента, оба экспортируемого типа
  • второй аргумент является указателем
  • одно возвращаемое значение типа error

Функция возвращает ошибку, если получатель не является экспортируемым типом или не имеет подходящих методов. Ошибка также записывается с помощью пакета log. Клиент обращается к каждому методу, используя строку вида "Type.Method", где Type — конкретный тип получателя.

func (*Server) RegisterName

func (server *Server) RegisterName(name string, rcvr any) error

RegisterName подобен Register, но вместо конкретного типа получателя использует указанное имя типа.

func (*Server) ServeCodec

func (server *Server) ServeCodec(codec ServerCodec)

ServeCodec подобен ServeConn, но использует указанный кодек для декодирования запросов и кодирования ответов.

func (*Server) ServeConn

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

ServeConn запускает сервер для одного соединения. ServeConn блокируется, обслуживая соединение, пока клиент не отключится. Обычно вызывающий код запускает ServeConn в операторе go. ServeConn использует в соединении формат передачи данных gob (см. пакет gob). Чтобы использовать другую кодировку, используйте ServeCodec. Информацию о параллельном доступе см. в комментарии к NewClient.

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

ServeRequest подобен ServeCodec, но синхронно обрабатывает один запрос. По завершении он не закрывает кодек.

type ServerCodec

ServerCodec реализует чтение RPC-запросов и запись RPC-ответов на стороне сервера в рамках сеанса RPC. Сервер вызывает ServerCodec.ReadRequestHeader и ServerCodec.ReadRequestBody попарно, чтобы читать запросы из соединения, и вызывает ServerCodec.WriteResponse, чтобы отправить ответ. По завершении работы с соединением сервер вызывает ServerCodec.Close. ReadRequestBody может вызываться с аргументом nil, чтобы принудительно прочитать и отбросить тело запроса. Сведения о параллельном доступе см. в комментарии к NewClient.

type ServerCodec interface {
    ReadRequestHeader(*Request) error
    ReadRequestBody(any) error
    WriteResponse(*Response, any) error

    // Close can be called multiple times and must be idempotent.
    Close() error
}

type ServerError

ServerError представляет ошибку, полученную от удаленной стороны RPC-соединения.

type ServerError string

func (ServerError) Error

func (e ServerError) Error() string

Подкаталоги

Имя Описание
..
jsonrpc Пакет jsonrpc реализует ClientCodec и ServerCodec для JSON-RPC 1.0 для пакета rpc.

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/net/rpc/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API