|
@@ -3,129 +3,129 @@
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
/*
|
|
|
- Package rpc is a trimmed down version of net/rpc in the standard library.
|
|
|
- Original doc:
|
|
|
+Package rpc is a trimmed down version of net/rpc in the standard library.
|
|
|
+Original doc:
|
|
|
|
|
|
- Package rpc provides access to the exported methods of an object across a
|
|
|
- network or other I/O connection. A server registers an object, making it visible
|
|
|
- as a service with the name of the type of the object. After registration, exported
|
|
|
- methods of the object will be accessible remotely. A server may register multiple
|
|
|
- objects (services) of different types but it is an error to register multiple
|
|
|
- objects of the same type.
|
|
|
+Package rpc provides access to the exported methods of an object across a
|
|
|
+network or other I/O connection. A server registers an object, making it visible
|
|
|
+as a service with the name of the type of the object. After registration, exported
|
|
|
+methods of the object will be accessible remotely. A server may register multiple
|
|
|
+objects (services) of different types but it is an error to register multiple
|
|
|
+objects of the same type.
|
|
|
|
|
|
- Only methods that satisfy these criteria will be made available for remote access;
|
|
|
- other methods will be ignored:
|
|
|
+Only methods that satisfy these criteria will be made available for remote access;
|
|
|
+other methods will be ignored:
|
|
|
|
|
|
- - the method's type is exported.
|
|
|
- - the method is exported.
|
|
|
- - the method has two arguments, both exported (or builtin) types.
|
|
|
- - the method's second argument is a pointer.
|
|
|
- - the method has return type error.
|
|
|
+ - the method's type is exported.
|
|
|
+ - the method is exported.
|
|
|
+ - the method has two arguments, both exported (or builtin) types.
|
|
|
+ - the method's second argument is a pointer.
|
|
|
+ - the method has return type error.
|
|
|
|
|
|
- In effect, the method must look schematically like
|
|
|
+In effect, the method must look schematically like
|
|
|
|
|
|
- func (t *T) MethodName(argType T1, replyType *T2) error
|
|
|
+ func (t *T) MethodName(argType T1, replyType *T2) error
|
|
|
|
|
|
- where T1 and T2 can be marshaled by encoding/gob.
|
|
|
- These requirements apply even if a different codec is used.
|
|
|
- (In the future, these requirements may soften for custom codecs.)
|
|
|
+where T1 and T2 can be marshaled by encoding/gob.
|
|
|
+These requirements apply even if a different codec is used.
|
|
|
+(In the future, these requirements may soften for custom codecs.)
|
|
|
|
|
|
- The method's first argument represents the arguments provided by the caller; the
|
|
|
- second argument represents the result parameters to be returned to the caller.
|
|
|
- The method's return value, if non-nil, is passed back as a string that the client
|
|
|
- sees as if created by errors.New. If an error is returned, the reply parameter
|
|
|
- will not be sent back to the client.
|
|
|
+The method's first argument represents the arguments provided by the caller; the
|
|
|
+second argument represents the result parameters to be returned to the caller.
|
|
|
+The method's return value, if non-nil, is passed back as a string that the client
|
|
|
+sees as if created by errors.New. If an error is returned, the reply parameter
|
|
|
+will not be sent back to the client.
|
|
|
|
|
|
- The server may handle requests on a single connection by calling ServeConn. More
|
|
|
- typically it will create a network listener and call Accept or, for an HTTP
|
|
|
- listener, HandleHTTP and http.Serve.
|
|
|
+The server may handle requests on a single connection by calling ServeConn. More
|
|
|
+typically it will create a network listener and call Accept or, for an HTTP
|
|
|
+listener, HandleHTTP and http.Serve.
|
|
|
|
|
|
- A client wishing to use the service establishes a connection and then invokes
|
|
|
- NewClient on the connection. The convenience function Dial (DialHTTP) performs
|
|
|
- both steps for a raw network connection (an HTTP connection). The resulting
|
|
|
- Client object has two methods, Call and Go, that specify the service and method to
|
|
|
- call, a pointer containing the arguments, and a pointer to receive the result
|
|
|
- parameters.
|
|
|
+A client wishing to use the service establishes a connection and then invokes
|
|
|
+NewClient on the connection. The convenience function Dial (DialHTTP) performs
|
|
|
+both steps for a raw network connection (an HTTP connection). The resulting
|
|
|
+Client object has two methods, Call and Go, that specify the service and method to
|
|
|
+call, a pointer containing the arguments, and a pointer to receive the result
|
|
|
+parameters.
|
|
|
|
|
|
- The Call method waits for the remote call to complete while the Go method
|
|
|
- launches the call asynchronously and signals completion using the Call
|
|
|
- structure's Done channel.
|
|
|
+The Call method waits for the remote call to complete while the Go method
|
|
|
+launches the call asynchronously and signals completion using the Call
|
|
|
+structure's Done channel.
|
|
|
|
|
|
- Unless an explicit codec is set up, package encoding/gob is used to
|
|
|
- transport the data.
|
|
|
+Unless an explicit codec is set up, package encoding/gob is used to
|
|
|
+transport the data.
|
|
|
|
|
|
- Here is a simple example. A server wishes to export an object of type Arith:
|
|
|
+Here is a simple example. A server wishes to export an object of type Arith:
|
|
|
|
|
|
- package server
|
|
|
+ package server
|
|
|
|
|
|
- import "errors"
|
|
|
+ import "errors"
|
|
|
|
|
|
- type Args struct {
|
|
|
- A, B int
|
|
|
- }
|
|
|
+ type Args struct {
|
|
|
+ A, B int
|
|
|
+ }
|
|
|
|
|
|
- type Quotient struct {
|
|
|
- Quo, Rem int
|
|
|
- }
|
|
|
+ type Quotient struct {
|
|
|
+ Quo, Rem int
|
|
|
+ }
|
|
|
|
|
|
- type Arith int
|
|
|
+ type Arith int
|
|
|
|
|
|
- func (t *Arith) Multiply(args *Args, reply *int) error {
|
|
|
- *reply = args.A * args.B
|
|
|
- return nil
|
|
|
- }
|
|
|
+ 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
|
|
|
+ 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
|
|
|
+ }
|
|
|
|
|
|
- The server calls (for HTTP service):
|
|
|
+The server calls (for HTTP service):
|
|
|
|
|
|
- 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 := 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)
|
|
|
|
|
|
- At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
|
|
|
- "Arith.Divide". To invoke one, a client first dials the server:
|
|
|
+At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
|
|
|
+"Arith.Divide". To invoke one, a client first dials the server:
|
|
|
|
|
|
- client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
|
|
|
- if err != nil {
|
|
|
- log.Fatal("dialing:", err)
|
|
|
- }
|
|
|
+ client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal("dialing:", err)
|
|
|
+ }
|
|
|
|
|
|
- Then it can make a remote call:
|
|
|
+Then it can make a remote call:
|
|
|
|
|
|
- // 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)
|
|
|
+ // 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
|
|
|
+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.
|
|
|
+ // 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.
|
|
|
|
|
|
- A server implementation will often provide a simple, type-safe wrapper for the
|
|
|
- client.
|
|
|
+A server implementation will often provide a simple, type-safe wrapper for the
|
|
|
+client.
|
|
|
|
|
|
- The net/rpc package is frozen and is not accepting new features.
|
|
|
+The net/rpc package is frozen and is not accepting new features.
|
|
|
*/
|
|
|
package rpc
|
|
|
|
|
@@ -209,10 +209,11 @@ func isExportedOrBuiltinType(t reflect.Type) bool {
|
|
|
|
|
|
// Register publishes in the server the set of methods of the
|
|
|
// receiver value that satisfy the following conditions:
|
|
|
-// - exported method of exported type
|
|
|
-// - two arguments, both of exported type
|
|
|
-// - the second argument is a pointer
|
|
|
-// - one return value, of type error
|
|
|
+// - exported method of exported type
|
|
|
+// - two arguments, both of exported type
|
|
|
+// - the second argument is a pointer
|
|
|
+// - one return value, of type error
|
|
|
+//
|
|
|
// It returns an error if the receiver is not an exported type or has
|
|
|
// no suitable methods. It also logs the error using package log.
|
|
|
// The client accesses each method using a string of the form "Type.Method",
|