Пакет rpc
Обзор
Пакет 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.
Реализация сервера часто предоставляет простую, безопасную с точки зрения типов оболочку для клиента.
Пакет net/rpc заморожен и не принимает новых функций.
Индекс
Файлы пакета
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, но синхронно обслуживает один запрос. Он не закрывает кодер по завершении.
тип 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.
}
тип Client
Client представляет клиент RPC. Может быть несколько активных вызовов, связанных с одним клиентом, и один клиент может использоваться несколькими горутинами одновременно.
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 выделит новый канал. Если не равен nil, done должен быть буферизованным, иначе Go намеренно вызовет аварийное завершение.
тип 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
} тип Request
Request — это заголовок, написанный перед каждым вызовом RPC. Он используется внутри, но здесь документируется для помощи в отладке, например, при анализе сетевого трафика.
type Request struct {
ServiceMethod string // format: "Service.Method"
Seq uint64 // sequence number chosen by client
// contains filtered or unexported fields
}
тип 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
}
тип Server
Server представляет собой сервер RPC.
type Server struct {
// contains filtered or unexported fields
}
функция NewServer
func NewServer() *Server
NewServer возвращает новый Server.
функция (*Server) Accept
func (server *Server) Accept(lis net.Listener)
Accept принимает подключения на прослушивателе и обрабатывает запросы для каждого входящего подключения. Accept блокируется до тех пор, пока прослушиватель не вернёт не nil-ошибку. Вызывающая сторона обычно вызывает Accept в операторе go.
функция (*Server) HandleHTTP
func (server *Server) HandleHTTP(rpcPath, debugPath string)
HandleHTTP регистрирует обработчик HTTP для сообщений RPC в rpcPath и обработчик отладки в debugPath. По-прежнему необходимо вызвать http.Serve(), обычно в операторе go.
функция (*Server) Register
func (server *Server) Register(rcvr any) error
Register публикует в сервере набор методов значения получателя, удовлетворяющие следующим условиям:
- экспортированный метод экспортированного типа
- два аргумента, оба экспортированного типа
- второй аргумент — указатель
- одно возвращаемое значение, типа error
Возвращает ошибку, если получатель не экспортированного типа или не имеет подходящих методов. Также регистрирует ошибку с помощью пакета log. Клиент обращается к каждому методу, используя строку вида «Тип.Метод», где Тип — конкретный тип получателя.
функция (*Server) RegisterName
func (server *Server) RegisterName(name string, rcvr any) error
RegisterName аналогична Register, но использует предоставленное имя для типа вместо конкретного типа получателя.
функция (*Server) ServeCodec
func (server *Server) ServeCodec(codec ServerCodec)
ServeCodec аналогична ServeConn, но использует указанный кодек для декодирования запросов и кодирования ответов.
функция (*Server) ServeConn
func (server *Server) ServeConn(conn io.ReadWriteCloser)
ServeConn запускает сервер на одном соединении. ServeConn блокируется, обрабатывая соединение до тех пор, пока клиент не разорвёт соединение. Вызывающая сторона обычно вызывает ServeConn в операторе go. ServeConn использует формат проводов gob (см. пакет gob) в соединении. Для использования альтернативного кодека используйте ServeCodec. См. комментарий к NewClient для информации о одновременном доступе.
функция (*Server) ServeHTTP
func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)
ServeHTTP реализует http.Handler, который отвечает на запросы RPC.
функция (*Server) ServeRequest
func (server *Server) ServeRequest(codec ServerCodec) error
ServeRequest аналогична ServeCodec, но синхронно обрабатывает один запрос. Она не закрывает кодек по завершении.
тип 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
} тип ServerError
ServerError представляет ошибку, возвращённую удалённой стороной подключения RPC.
type ServerError string
функция (ServerError) Error
func (e ServerError) Error() string
Подкаталоги
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/net/rpc/