1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
6 Package rpc provides access to the exported methods of an object across a
7 network or other I/O connection. A server registers an object, making it visible
8 as a service with the name of the type of the object. After registration, exported
9 methods of the object will be accessible remotely. A server may register multiple
10 objects (services) of different types but it is an error to register multiple
11 objects of the same type.
13 Only methods that satisfy these criteria will be made available for remote access;
14 other methods will be ignored:
16 - the method's type is exported.
17 - the method is exported.
18 - the method has two arguments, both exported (or builtin) types.
19 - the method's second argument is a pointer.
20 - the method has return type error.
22 In effect, the method must look schematically like
24 func (t *T) MethodName(argType T1, replyType *T2) error
26 where T1 and T2 can be marshaled by encoding/gob.
27 These requirements apply even if a different codec is used.
28 (In the future, these requirements may soften for custom codecs.)
30 The method's first argument represents the arguments provided by the caller; the
31 second argument represents the result parameters to be returned to the caller.
32 The method's return value, if non-nil, is passed back as a string that the client
33 sees as if created by errors.New. If an error is returned, the reply parameter
34 will not be sent back to the client.
36 The server may handle requests on a single connection by calling ServeConn. More
37 typically it will create a network listener and call Accept or, for an HTTP
38 listener, HandleHTTP and http.Serve.
40 A client wishing to use the service establishes a connection and then invokes
41 NewClient on the connection. The convenience function Dial (DialHTTP) performs
42 both steps for a raw network connection (an HTTP connection). The resulting
43 Client object has two methods, Call and Go, that specify the service and method to
44 call, a pointer containing the arguments, and a pointer to receive the result
47 The Call method waits for the remote call to complete while the Go method
48 launches the call asynchronously and signals completion using the Call
49 structure's Done channel.
51 Unless an explicit codec is set up, package encoding/gob is used to
54 Here is a simple example. A server wishes to export an object of type Arith:
64 type Quotient struct {
70 func (t *Arith) Multiply(args *Args, reply *int) error {
71 *reply = args.A * args.B
75 func (t *Arith) Divide(args *Args, quo *Quotient) error {
77 return errors.New("divide by zero")
79 quo.Quo = args.A / args.B
80 quo.Rem = args.A % args.B
84 The server calls (for HTTP service):
89 l, e := net.Listen("tcp", ":1234")
91 log.Fatal("listen error:", e)
95 At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
96 "Arith.Divide". To invoke one, a client first dials the server:
98 client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
100 log.Fatal("dialing:", err)
103 Then it can make a remote call:
106 args := &server.Args{7,8}
108 err = client.Call("Arith.Multiply", args, &reply)
110 log.Fatal("arith error:", err)
112 fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
117 quotient := new(Quotient)
118 divCall := client.Go("Arith.Divide", args, quotient, nil)
119 replyCall := <-divCall.Done // will be equal to divCall
120 // check errors, print, etc.
122 A server implementation will often provide a simple, type-safe wrapper for the
125 The net/rpc package is frozen and is not accepting new features.
145 // Defaults used by HandleHTTP
146 DefaultRPCPath
= "/_goRPC_"
147 DefaultDebugPath
= "/debug/rpc"
150 // Precompute the reflect type for error. Can't use error directly
151 // because Typeof takes an empty interface value. This is annoying.
152 var typeOfError
= reflect
.TypeOf((*error
)(nil)).Elem()
154 type methodType
struct {
155 sync
.Mutex
// protects counters
156 method reflect
.Method
158 ReplyType reflect
.Type
162 type service
struct {
163 name
string // name of service
164 rcvr reflect
.Value
// receiver of methods for the service
165 typ reflect
.Type
// type of the receiver
166 method
map[string]*methodType
// registered methods
169 // Request is a header written before every RPC call. It is used internally
170 // but documented here as an aid to debugging, such as when analyzing
172 type Request
struct {
173 ServiceMethod
string // format: "Service.Method"
174 Seq
uint64 // sequence number chosen by client
175 next
*Request
// for free list in Server
178 // Response is a header written before every RPC return. It is used internally
179 // but documented here as an aid to debugging, such as when analyzing
181 type Response
struct {
182 ServiceMethod
string // echoes that of the Request
183 Seq
uint64 // echoes that of the request
184 Error
string // error, if any.
185 next
*Response
// for free list in Server
188 // Server represents an RPC Server.
190 serviceMap sync
.Map
// map[string]*service
191 reqLock sync
.Mutex
// protects freeReq
193 respLock sync
.Mutex
// protects freeResp
197 // NewServer returns a new Server.
198 func NewServer() *Server
{
202 // DefaultServer is the default instance of *Server.
203 var DefaultServer
= NewServer()
205 // Is this an exported - upper case - name?
206 func isExported(name
string) bool {
207 rune
, _
:= utf8
.DecodeRuneInString(name
)
208 return unicode
.IsUpper(rune
)
211 // Is this type exported or a builtin?
212 func isExportedOrBuiltinType(t reflect
.Type
) bool {
213 for t
.Kind() == reflect
.Ptr
{
216 // PkgPath will be non-empty even for an exported type,
217 // so we need to check the type name as well.
218 return isExported(t
.Name()) || t
.PkgPath() == ""
221 // Register publishes in the server the set of methods of the
222 // receiver value that satisfy the following conditions:
223 // - exported method of exported type
224 // - two arguments, both of exported type
225 // - the second argument is a pointer
226 // - one return value, of type error
227 // It returns an error if the receiver is not an exported type or has
228 // no suitable methods. It also logs the error using package log.
229 // The client accesses each method using a string of the form "Type.Method",
230 // where Type is the receiver's concrete type.
231 func (server
*Server
) Register(rcvr
interface{}) error
{
232 return server
.register(rcvr
, "", false)
235 // RegisterName is like Register but uses the provided name for the type
236 // instead of the receiver's concrete type.
237 func (server
*Server
) RegisterName(name
string, rcvr
interface{}) error
{
238 return server
.register(rcvr
, name
, true)
241 func (server
*Server
) register(rcvr
interface{}, name
string, useName
bool) error
{
243 s
.typ
= reflect
.TypeOf(rcvr
)
244 s
.rcvr
= reflect
.ValueOf(rcvr
)
245 sname
:= reflect
.Indirect(s
.rcvr
).Type().Name()
250 s
:= "rpc.Register: no service name for type " + s
.typ
.String()
254 if !isExported(sname
) && !useName
{
255 s
:= "rpc.Register: type " + sname
+ " is not exported"
261 // Install the methods
262 s
.method
= suitableMethods(s
.typ
, true)
264 if len(s
.method
) == 0 {
267 // To help the user, see if a pointer receiver would work.
268 method
:= suitableMethods(reflect
.PtrTo(s
.typ
), false)
269 if len(method
) != 0 {
270 str
= "rpc.Register: type " + sname
+ " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
272 str
= "rpc.Register: type " + sname
+ " has no exported methods of suitable type"
275 return errors
.New(str
)
278 if _
, dup
:= server
.serviceMap
.LoadOrStore(sname
, s
); dup
{
279 return errors
.New("rpc: service already defined: " + sname
)
284 // suitableMethods returns suitable Rpc methods of typ, it will report
285 // error using log if reportErr is true.
286 func suitableMethods(typ reflect
.Type
, reportErr
bool) map[string]*methodType
{
287 methods
:= make(map[string]*methodType
)
288 for m
:= 0; m
< typ
.NumMethod(); m
++ {
289 method
:= typ
.Method(m
)
292 // Method must be exported.
293 if method
.PkgPath
!= "" {
296 // Method needs three ins: receiver, *args, *reply.
297 if mtype
.NumIn() != 3 {
299 log
.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname
, mtype
.NumIn())
303 // First arg need not be a pointer.
304 argType
:= mtype
.In(1)
305 if !isExportedOrBuiltinType(argType
) {
307 log
.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname
, argType
)
311 // Second arg must be a pointer.
312 replyType
:= mtype
.In(2)
313 if replyType
.Kind() != reflect
.Ptr
{
315 log
.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname
, replyType
)
319 // Reply type must be exported.
320 if !isExportedOrBuiltinType(replyType
) {
322 log
.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname
, replyType
)
326 // Method needs one out.
327 if mtype
.NumOut() != 1 {
329 log
.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname
, mtype
.NumOut())
333 // The return type of the method must be error.
334 if returnType
:= mtype
.Out(0); returnType
!= typeOfError
{
336 log
.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname
, returnType
)
340 methods
[mname
] = &methodType
{method
: method
, ArgType
: argType
, ReplyType
: replyType
}
345 // A value sent as a placeholder for the server's response value when the server
346 // receives an invalid request. It is never decoded by the client since the Response
347 // contains an error when it is used.
348 var invalidRequest
= struct{}{}
350 func (server
*Server
) sendResponse(sending
*sync
.Mutex
, req
*Request
, reply
interface{}, codec ServerCodec
, errmsg
string) {
351 resp
:= server
.getResponse()
352 // Encode the response header
353 resp
.ServiceMethod
= req
.ServiceMethod
356 reply
= invalidRequest
360 err
:= codec
.WriteResponse(resp
, reply
)
361 if debugLog
&& err
!= nil {
362 log
.Println("rpc: writing response:", err
)
365 server
.freeResponse(resp
)
368 func (m
*methodType
) NumCalls() (n
uint) {
375 func (s
*service
) call(server
*Server
, sending
*sync
.Mutex
, wg
*sync
.WaitGroup
, mtype
*methodType
, req
*Request
, argv
, replyv reflect
.Value
, codec ServerCodec
) {
382 function
:= mtype
.method
.Func
383 // Invoke the method, providing a new value for the reply.
384 returnValues
:= function
.Call([]reflect
.Value
{s
.rcvr
, argv
, replyv
})
385 // The return value for the method is an error.
386 errInter
:= returnValues
[0].Interface()
389 errmsg
= errInter
.(error
).Error()
391 server
.sendResponse(sending
, req
, replyv
.Interface(), codec
, errmsg
)
392 server
.freeRequest(req
)
395 type gobServerCodec
struct {
396 rwc io
.ReadWriteCloser
403 func (c
*gobServerCodec
) ReadRequestHeader(r
*Request
) error
{
404 return c
.dec
.Decode(r
)
407 func (c
*gobServerCodec
) ReadRequestBody(body
interface{}) error
{
408 return c
.dec
.Decode(body
)
411 func (c
*gobServerCodec
) WriteResponse(r
*Response
, body
interface{}) (err error
) {
412 if err
= c
.enc
.Encode(r
); err
!= nil {
413 if c
.encBuf
.Flush() == nil {
414 // Gob couldn't encode the header. Should not happen, so if it does,
415 // shut down the connection to signal that the connection is broken.
416 log
.Println("rpc: gob error encoding response:", err
)
421 if err
= c
.enc
.Encode(body
); err
!= nil {
422 if c
.encBuf
.Flush() == nil {
423 // Was a gob problem encoding the body but the header has been written.
424 // Shut down the connection to signal that the connection is broken.
425 log
.Println("rpc: gob error encoding body:", err
)
430 return c
.encBuf
.Flush()
433 func (c
*gobServerCodec
) Close() error
{
435 // Only call c.rwc.Close once; otherwise the semantics are undefined.
442 // ServeConn runs the server on a single connection.
443 // ServeConn blocks, serving the connection until the client hangs up.
444 // The caller typically invokes ServeConn in a go statement.
445 // ServeConn uses the gob wire format (see package gob) on the
446 // connection. To use an alternate codec, use ServeCodec.
447 func (server
*Server
) ServeConn(conn io
.ReadWriteCloser
) {
448 buf
:= bufio
.NewWriter(conn
)
449 srv
:= &gobServerCodec
{
451 dec
: gob
.NewDecoder(conn
),
452 enc
: gob
.NewEncoder(buf
),
455 server
.ServeCodec(srv
)
458 // ServeCodec is like ServeConn but uses the specified codec to
459 // decode requests and encode responses.
460 func (server
*Server
) ServeCodec(codec ServerCodec
) {
461 sending
:= new(sync
.Mutex
)
462 wg
:= new(sync
.WaitGroup
)
464 service
, mtype
, req
, argv
, replyv
, keepReading
, err
:= server
.readRequest(codec
)
466 if debugLog
&& err
!= io
.EOF
{
467 log
.Println("rpc:", err
)
472 // send a response if we actually managed to read a header.
474 server
.sendResponse(sending
, req
, invalidRequest
, codec
, err
.Error())
475 server
.freeRequest(req
)
480 go service
.call(server
, sending
, wg
, mtype
, req
, argv
, replyv
, codec
)
482 // We've seen that there are no more requests.
483 // Wait for responses to be sent before closing codec.
488 // ServeRequest is like ServeCodec but synchronously serves a single request.
489 // It does not close the codec upon completion.
490 func (server
*Server
) ServeRequest(codec ServerCodec
) error
{
491 sending
:= new(sync
.Mutex
)
492 service
, mtype
, req
, argv
, replyv
, keepReading
, err
:= server
.readRequest(codec
)
497 // send a response if we actually managed to read a header.
499 server
.sendResponse(sending
, req
, invalidRequest
, codec
, err
.Error())
500 server
.freeRequest(req
)
504 service
.call(server
, sending
, nil, mtype
, req
, argv
, replyv
, codec
)
508 func (server
*Server
) getRequest() *Request
{
509 server
.reqLock
.Lock()
510 req
:= server
.freeReq
514 server
.freeReq
= req
.next
517 server
.reqLock
.Unlock()
521 func (server
*Server
) freeRequest(req
*Request
) {
522 server
.reqLock
.Lock()
523 req
.next
= server
.freeReq
525 server
.reqLock
.Unlock()
528 func (server
*Server
) getResponse() *Response
{
529 server
.respLock
.Lock()
530 resp
:= server
.freeResp
534 server
.freeResp
= resp
.next
537 server
.respLock
.Unlock()
541 func (server
*Server
) freeResponse(resp
*Response
) {
542 server
.respLock
.Lock()
543 resp
.next
= server
.freeResp
544 server
.freeResp
= resp
545 server
.respLock
.Unlock()
548 func (server
*Server
) readRequest(codec ServerCodec
) (service
*service
, mtype
*methodType
, req
*Request
, argv
, replyv reflect
.Value
, keepReading
bool, err error
) {
549 service
, mtype
, req
, keepReading
, err
= server
.readRequestHeader(codec
)
555 codec
.ReadRequestBody(nil)
559 // Decode the argument value.
560 argIsValue
:= false // if true, need to indirect before calling.
561 if mtype
.ArgType
.Kind() == reflect
.Ptr
{
562 argv
= reflect
.New(mtype
.ArgType
.Elem())
564 argv
= reflect
.New(mtype
.ArgType
)
567 // argv guaranteed to be a pointer now.
568 if err
= codec
.ReadRequestBody(argv
.Interface()); err
!= nil {
575 replyv
= reflect
.New(mtype
.ReplyType
.Elem())
577 switch mtype
.ReplyType
.Elem().Kind() {
579 replyv
.Elem().Set(reflect
.MakeMap(mtype
.ReplyType
.Elem()))
581 replyv
.Elem().Set(reflect
.MakeSlice(mtype
.ReplyType
.Elem(), 0, 0))
586 func (server
*Server
) readRequestHeader(codec ServerCodec
) (svc
*service
, mtype
*methodType
, req
*Request
, keepReading
bool, err error
) {
587 // Grab the request header.
588 req
= server
.getRequest()
589 err
= codec
.ReadRequestHeader(req
)
592 if err
== io
.EOF || err
== io
.ErrUnexpectedEOF
{
595 err
= errors
.New("rpc: server cannot decode request: " + err
.Error())
599 // We read the header successfully. If we see an error now,
600 // we can still recover and move on to the next request.
603 dot
:= strings
.LastIndex(req
.ServiceMethod
, ".")
605 err
= errors
.New("rpc: service/method request ill-formed: " + req
.ServiceMethod
)
608 serviceName
:= req
.ServiceMethod
[:dot
]
609 methodName
:= req
.ServiceMethod
[dot
+1:]
611 // Look up the request.
612 svci
, ok
:= server
.serviceMap
.Load(serviceName
)
614 err
= errors
.New("rpc: can't find service " + req
.ServiceMethod
)
617 svc
= svci
.(*service
)
618 mtype
= svc
.method
[methodName
]
620 err
= errors
.New("rpc: can't find method " + req
.ServiceMethod
)
625 // Accept accepts connections on the listener and serves requests
626 // for each incoming connection. Accept blocks until the listener
627 // returns a non-nil error. The caller typically invokes Accept in a
629 func (server
*Server
) Accept(lis net
.Listener
) {
631 conn
, err
:= lis
.Accept()
633 log
.Print("rpc.Serve: accept:", err
.Error())
636 go server
.ServeConn(conn
)
640 // Register publishes the receiver's methods in the DefaultServer.
641 func Register(rcvr
interface{}) error
{ return DefaultServer
.Register(rcvr
) }
643 // RegisterName is like Register but uses the provided name for the type
644 // instead of the receiver's concrete type.
645 func RegisterName(name
string, rcvr
interface{}) error
{
646 return DefaultServer
.RegisterName(name
, rcvr
)
649 // A ServerCodec implements reading of RPC requests and writing of
650 // RPC responses for the server side of an RPC session.
651 // The server calls ReadRequestHeader and ReadRequestBody in pairs
652 // to read requests from the connection, and it calls WriteResponse to
653 // write a response back. The server calls Close when finished with the
654 // connection. ReadRequestBody may be called with a nil
655 // argument to force the body of the request to be read and discarded.
656 type ServerCodec
interface {
657 ReadRequestHeader(*Request
) error
658 ReadRequestBody(interface{}) error
659 // WriteResponse must be safe for concurrent use by multiple goroutines.
660 WriteResponse(*Response
, interface{}) error
665 // ServeConn runs the DefaultServer on a single connection.
666 // ServeConn blocks, serving the connection until the client hangs up.
667 // The caller typically invokes ServeConn in a go statement.
668 // ServeConn uses the gob wire format (see package gob) on the
669 // connection. To use an alternate codec, use ServeCodec.
670 func ServeConn(conn io
.ReadWriteCloser
) {
671 DefaultServer
.ServeConn(conn
)
674 // ServeCodec is like ServeConn but uses the specified codec to
675 // decode requests and encode responses.
676 func ServeCodec(codec ServerCodec
) {
677 DefaultServer
.ServeCodec(codec
)
680 // ServeRequest is like ServeCodec but synchronously serves a single request.
681 // It does not close the codec upon completion.
682 func ServeRequest(codec ServerCodec
) error
{
683 return DefaultServer
.ServeRequest(codec
)
686 // Accept accepts connections on the listener and serves requests
687 // to DefaultServer for each incoming connection.
688 // Accept blocks; the caller typically invokes it in a go statement.
689 func Accept(lis net
.Listener
) { DefaultServer
.Accept(lis
) }
691 // Can connect to RPC service using HTTP CONNECT to rpcPath.
692 var connected
= "200 Connected to Go RPC"
694 // ServeHTTP implements an http.Handler that answers RPC requests.
695 func (server
*Server
) ServeHTTP(w http
.ResponseWriter
, req
*http
.Request
) {
696 if req
.Method
!= "CONNECT" {
697 w
.Header().Set("Content-Type", "text/plain; charset=utf-8")
698 w
.WriteHeader(http
.StatusMethodNotAllowed
)
699 io
.WriteString(w
, "405 must CONNECT\n")
702 conn
, _
, err
:= w
.(http
.Hijacker
).Hijack()
704 log
.Print("rpc hijacking ", req
.RemoteAddr
, ": ", err
.Error())
707 io
.WriteString(conn
, "HTTP/1.0 "+connected
+"\n\n")
708 server
.ServeConn(conn
)
711 // HandleHTTP registers an HTTP handler for RPC messages on rpcPath,
712 // and a debugging handler on debugPath.
713 // It is still necessary to invoke http.Serve(), typically in a go statement.
714 func (server
*Server
) HandleHTTP(rpcPath
, debugPath
string) {
715 http
.Handle(rpcPath
, server
)
716 http
.Handle(debugPath
, debugHTTP
{server
})
719 // HandleHTTP registers an HTTP handler for RPC messages to DefaultServer
720 // on DefaultRPCPath and a debugging handler on DefaultDebugPath.
721 // It is still necessary to invoke http.Serve(), typically in a go statement.
723 DefaultServer
.HandleHTTP(DefaultRPCPath
, DefaultDebugPath
)