github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/src/net/rpc/server.go (about) 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. 4 5 /* 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. 12 13 Only methods that satisfy these criteria will be made available for remote access; 14 other methods will be ignored: 15 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. 21 22 In effect, the method must look schematically like 23 24 func (t *T) MethodName(argType T1, replyType *T2) error 25 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.) 29 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. 35 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. 39 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 45 parameters. 46 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. 50 51 Unless an explicit codec is set up, package encoding/gob is used to 52 transport the data. 53 54 Here is a simple example. A server wishes to export an object of type Arith: 55 56 package server 57 58 import "errors" 59 60 type Args struct { 61 A, B int 62 } 63 64 type Quotient struct { 65 Quo, Rem int 66 } 67 68 type Arith int 69 70 func (t *Arith) Multiply(args *Args, reply *int) error { 71 *reply = args.A * args.B 72 return nil 73 } 74 75 func (t *Arith) Divide(args *Args, quo *Quotient) error { 76 if args.B == 0 { 77 return errors.New("divide by zero") 78 } 79 quo.Quo = args.A / args.B 80 quo.Rem = args.A % args.B 81 return nil 82 } 83 84 The server calls (for HTTP service): 85 86 arith := new(Arith) 87 rpc.Register(arith) 88 rpc.HandleHTTP() 89 l, e := net.Listen("tcp", ":1234") 90 if e != nil { 91 log.Fatal("listen error:", e) 92 } 93 go http.Serve(l, nil) 94 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: 97 98 client, err := rpc.DialHTTP("tcp", serverAddress + ":1234") 99 if err != nil { 100 log.Fatal("dialing:", err) 101 } 102 103 Then it can make a remote call: 104 105 // Synchronous call 106 args := &server.Args{7,8} 107 var reply int 108 err = client.Call("Arith.Multiply", args, &reply) 109 if err != nil { 110 log.Fatal("arith error:", err) 111 } 112 fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply) 113 114 or 115 116 // Asynchronous call 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. 121 122 A server implementation will often provide a simple, type-safe wrapper for the 123 client. 124 125 The net/rpc package is frozen and is not accepting new features. 126 */ 127 package rpc 128 129 import ( 130 "bufio" 131 "encoding/gob" 132 "errors" 133 "io" 134 "log" 135 "net" 136 "net/http" 137 "reflect" 138 "strings" 139 "sync" 140 "unicode" 141 "unicode/utf8" 142 ) 143 144 const ( 145 // Defaults used by HandleHTTP 146 DefaultRPCPath = "/_goRPC_" 147 DefaultDebugPath = "/debug/rpc" 148 ) 149 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() 153 154 type methodType struct { 155 sync.Mutex // protects counters 156 method reflect.Method 157 ArgType reflect.Type 158 ReplyType reflect.Type 159 numCalls uint 160 } 161 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 167 } 168 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 171 // network traffic. 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 176 } 177 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 180 // network traffic. 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 186 } 187 188 // Server represents an RPC Server. 189 type Server struct { 190 mu sync.RWMutex // protects the serviceMap 191 serviceMap map[string]*service 192 reqLock sync.Mutex // protects freeReq 193 freeReq *Request 194 respLock sync.Mutex // protects freeResp 195 freeResp *Response 196 } 197 198 // NewServer returns a new Server. 199 func NewServer() *Server { 200 return &Server{serviceMap: make(map[string]*service)} 201 } 202 203 // DefaultServer is the default instance of *Server. 204 var DefaultServer = NewServer() 205 206 // Is this an exported - upper case - name? 207 func isExported(name string) bool { 208 rune, _ := utf8.DecodeRuneInString(name) 209 return unicode.IsUpper(rune) 210 } 211 212 // Is this type exported or a builtin? 213 func isExportedOrBuiltinType(t reflect.Type) bool { 214 for t.Kind() == reflect.Ptr { 215 t = t.Elem() 216 } 217 // PkgPath will be non-empty even for an exported type, 218 // so we need to check the type name as well. 219 return isExported(t.Name()) || t.PkgPath() == "" 220 } 221 222 // Register publishes in the server the set of methods of the 223 // receiver value that satisfy the following conditions: 224 // - exported method of exported type 225 // - two arguments, both of exported type 226 // - the second argument is a pointer 227 // - one return value, of type error 228 // It returns an error if the receiver is not an exported type or has 229 // no suitable methods. It also logs the error using package log. 230 // The client accesses each method using a string of the form "Type.Method", 231 // where Type is the receiver's concrete type. 232 func (server *Server) Register(rcvr interface{}) error { 233 return server.register(rcvr, "", false) 234 } 235 236 // RegisterName is like Register but uses the provided name for the type 237 // instead of the receiver's concrete type. 238 func (server *Server) RegisterName(name string, rcvr interface{}) error { 239 return server.register(rcvr, name, true) 240 } 241 242 func (server *Server) register(rcvr interface{}, name string, useName bool) error { 243 server.mu.Lock() 244 defer server.mu.Unlock() 245 if server.serviceMap == nil { 246 server.serviceMap = make(map[string]*service) 247 } 248 s := new(service) 249 s.typ = reflect.TypeOf(rcvr) 250 s.rcvr = reflect.ValueOf(rcvr) 251 sname := reflect.Indirect(s.rcvr).Type().Name() 252 if useName { 253 sname = name 254 } 255 if sname == "" { 256 s := "rpc.Register: no service name for type " + s.typ.String() 257 log.Print(s) 258 return errors.New(s) 259 } 260 if !isExported(sname) && !useName { 261 s := "rpc.Register: type " + sname + " is not exported" 262 log.Print(s) 263 return errors.New(s) 264 } 265 if _, present := server.serviceMap[sname]; present { 266 return errors.New("rpc: service already defined: " + sname) 267 } 268 s.name = sname 269 270 // Install the methods 271 s.method = suitableMethods(s.typ, true) 272 273 if len(s.method) == 0 { 274 str := "" 275 276 // To help the user, see if a pointer receiver would work. 277 method := suitableMethods(reflect.PtrTo(s.typ), false) 278 if len(method) != 0 { 279 str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)" 280 } else { 281 str = "rpc.Register: type " + sname + " has no exported methods of suitable type" 282 } 283 log.Print(str) 284 return errors.New(str) 285 } 286 server.serviceMap[s.name] = s 287 return nil 288 } 289 290 // suitableMethods returns suitable Rpc methods of typ, it will report 291 // error using log if reportErr is true. 292 func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType { 293 methods := make(map[string]*methodType) 294 for m := 0; m < typ.NumMethod(); m++ { 295 method := typ.Method(m) 296 mtype := method.Type 297 mname := method.Name 298 // Method must be exported. 299 if method.PkgPath != "" { 300 continue 301 } 302 // Method needs three ins: receiver, *args, *reply. 303 if mtype.NumIn() != 3 { 304 if reportErr { 305 log.Println("method", mname, "has wrong number of ins:", mtype.NumIn()) 306 } 307 continue 308 } 309 // First arg need not be a pointer. 310 argType := mtype.In(1) 311 if !isExportedOrBuiltinType(argType) { 312 if reportErr { 313 log.Println(mname, "argument type not exported:", argType) 314 } 315 continue 316 } 317 // Second arg must be a pointer. 318 replyType := mtype.In(2) 319 if replyType.Kind() != reflect.Ptr { 320 if reportErr { 321 log.Println("method", mname, "reply type not a pointer:", replyType) 322 } 323 continue 324 } 325 // Reply type must be exported. 326 if !isExportedOrBuiltinType(replyType) { 327 if reportErr { 328 log.Println("method", mname, "reply type not exported:", replyType) 329 } 330 continue 331 } 332 // Method needs one out. 333 if mtype.NumOut() != 1 { 334 if reportErr { 335 log.Println("method", mname, "has wrong number of outs:", mtype.NumOut()) 336 } 337 continue 338 } 339 // The return type of the method must be error. 340 if returnType := mtype.Out(0); returnType != typeOfError { 341 if reportErr { 342 log.Println("method", mname, "returns", returnType.String(), "not error") 343 } 344 continue 345 } 346 methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType} 347 } 348 return methods 349 } 350 351 // A value sent as a placeholder for the server's response value when the server 352 // receives an invalid request. It is never decoded by the client since the Response 353 // contains an error when it is used. 354 var invalidRequest = struct{}{} 355 356 func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply interface{}, codec ServerCodec, errmsg string) { 357 resp := server.getResponse() 358 // Encode the response header 359 resp.ServiceMethod = req.ServiceMethod 360 if errmsg != "" { 361 resp.Error = errmsg 362 reply = invalidRequest 363 } 364 resp.Seq = req.Seq 365 sending.Lock() 366 err := codec.WriteResponse(resp, reply) 367 if debugLog && err != nil { 368 log.Println("rpc: writing response:", err) 369 } 370 sending.Unlock() 371 server.freeResponse(resp) 372 } 373 374 func (m *methodType) NumCalls() (n uint) { 375 m.Lock() 376 n = m.numCalls 377 m.Unlock() 378 return n 379 } 380 381 func (s *service) call(server *Server, sending *sync.Mutex, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) { 382 mtype.Lock() 383 mtype.numCalls++ 384 mtype.Unlock() 385 function := mtype.method.Func 386 // Invoke the method, providing a new value for the reply. 387 returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv}) 388 // The return value for the method is an error. 389 errInter := returnValues[0].Interface() 390 errmsg := "" 391 if errInter != nil { 392 errmsg = errInter.(error).Error() 393 } 394 server.sendResponse(sending, req, replyv.Interface(), codec, errmsg) 395 server.freeRequest(req) 396 } 397 398 type gobServerCodec struct { 399 rwc io.ReadWriteCloser 400 dec *gob.Decoder 401 enc *gob.Encoder 402 encBuf *bufio.Writer 403 closed bool 404 } 405 406 func (c *gobServerCodec) ReadRequestHeader(r *Request) error { 407 return c.dec.Decode(r) 408 } 409 410 func (c *gobServerCodec) ReadRequestBody(body interface{}) error { 411 return c.dec.Decode(body) 412 } 413 414 func (c *gobServerCodec) WriteResponse(r *Response, body interface{}) (err error) { 415 if err = c.enc.Encode(r); err != nil { 416 if c.encBuf.Flush() == nil { 417 // Gob couldn't encode the header. Should not happen, so if it does, 418 // shut down the connection to signal that the connection is broken. 419 log.Println("rpc: gob error encoding response:", err) 420 c.Close() 421 } 422 return 423 } 424 if err = c.enc.Encode(body); err != nil { 425 if c.encBuf.Flush() == nil { 426 // Was a gob problem encoding the body but the header has been written. 427 // Shut down the connection to signal that the connection is broken. 428 log.Println("rpc: gob error encoding body:", err) 429 c.Close() 430 } 431 return 432 } 433 return c.encBuf.Flush() 434 } 435 436 func (c *gobServerCodec) Close() error { 437 if c.closed { 438 // Only call c.rwc.Close once; otherwise the semantics are undefined. 439 return nil 440 } 441 c.closed = true 442 return c.rwc.Close() 443 } 444 445 // ServeConn runs the server on a single connection. 446 // ServeConn blocks, serving the connection until the client hangs up. 447 // The caller typically invokes ServeConn in a go statement. 448 // ServeConn uses the gob wire format (see package gob) on the 449 // connection. To use an alternate codec, use ServeCodec. 450 func (server *Server) ServeConn(conn io.ReadWriteCloser) { 451 buf := bufio.NewWriter(conn) 452 srv := &gobServerCodec{ 453 rwc: conn, 454 dec: gob.NewDecoder(conn), 455 enc: gob.NewEncoder(buf), 456 encBuf: buf, 457 } 458 server.ServeCodec(srv) 459 } 460 461 // ServeCodec is like ServeConn but uses the specified codec to 462 // decode requests and encode responses. 463 func (server *Server) ServeCodec(codec ServerCodec) { 464 sending := new(sync.Mutex) 465 for { 466 service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec) 467 if err != nil { 468 if debugLog && err != io.EOF { 469 log.Println("rpc:", err) 470 } 471 if !keepReading { 472 break 473 } 474 // send a response if we actually managed to read a header. 475 if req != nil { 476 server.sendResponse(sending, req, invalidRequest, codec, err.Error()) 477 server.freeRequest(req) 478 } 479 continue 480 } 481 go service.call(server, sending, mtype, req, argv, replyv, codec) 482 } 483 codec.Close() 484 } 485 486 // ServeRequest is like ServeCodec but synchronously serves a single request. 487 // It does not close the codec upon completion. 488 func (server *Server) ServeRequest(codec ServerCodec) error { 489 sending := new(sync.Mutex) 490 service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec) 491 if err != nil { 492 if !keepReading { 493 return err 494 } 495 // send a response if we actually managed to read a header. 496 if req != nil { 497 server.sendResponse(sending, req, invalidRequest, codec, err.Error()) 498 server.freeRequest(req) 499 } 500 return err 501 } 502 service.call(server, sending, mtype, req, argv, replyv, codec) 503 return nil 504 } 505 506 func (server *Server) getRequest() *Request { 507 server.reqLock.Lock() 508 req := server.freeReq 509 if req == nil { 510 req = new(Request) 511 } else { 512 server.freeReq = req.next 513 *req = Request{} 514 } 515 server.reqLock.Unlock() 516 return req 517 } 518 519 func (server *Server) freeRequest(req *Request) { 520 server.reqLock.Lock() 521 req.next = server.freeReq 522 server.freeReq = req 523 server.reqLock.Unlock() 524 } 525 526 func (server *Server) getResponse() *Response { 527 server.respLock.Lock() 528 resp := server.freeResp 529 if resp == nil { 530 resp = new(Response) 531 } else { 532 server.freeResp = resp.next 533 *resp = Response{} 534 } 535 server.respLock.Unlock() 536 return resp 537 } 538 539 func (server *Server) freeResponse(resp *Response) { 540 server.respLock.Lock() 541 resp.next = server.freeResp 542 server.freeResp = resp 543 server.respLock.Unlock() 544 } 545 546 func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) { 547 service, mtype, req, keepReading, err = server.readRequestHeader(codec) 548 if err != nil { 549 if !keepReading { 550 return 551 } 552 // discard body 553 codec.ReadRequestBody(nil) 554 return 555 } 556 557 // Decode the argument value. 558 argIsValue := false // if true, need to indirect before calling. 559 if mtype.ArgType.Kind() == reflect.Ptr { 560 argv = reflect.New(mtype.ArgType.Elem()) 561 } else { 562 argv = reflect.New(mtype.ArgType) 563 argIsValue = true 564 } 565 // argv guaranteed to be a pointer now. 566 if err = codec.ReadRequestBody(argv.Interface()); err != nil { 567 return 568 } 569 if argIsValue { 570 argv = argv.Elem() 571 } 572 573 replyv = reflect.New(mtype.ReplyType.Elem()) 574 return 575 } 576 577 func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mtype *methodType, req *Request, keepReading bool, err error) { 578 // Grab the request header. 579 req = server.getRequest() 580 err = codec.ReadRequestHeader(req) 581 if err != nil { 582 req = nil 583 if err == io.EOF || err == io.ErrUnexpectedEOF { 584 return 585 } 586 err = errors.New("rpc: server cannot decode request: " + err.Error()) 587 return 588 } 589 590 // We read the header successfully. If we see an error now, 591 // we can still recover and move on to the next request. 592 keepReading = true 593 594 dot := strings.LastIndex(req.ServiceMethod, ".") 595 if dot < 0 { 596 err = errors.New("rpc: service/method request ill-formed: " + req.ServiceMethod) 597 return 598 } 599 serviceName := req.ServiceMethod[:dot] 600 methodName := req.ServiceMethod[dot+1:] 601 602 // Look up the request. 603 server.mu.RLock() 604 service = server.serviceMap[serviceName] 605 server.mu.RUnlock() 606 if service == nil { 607 err = errors.New("rpc: can't find service " + req.ServiceMethod) 608 return 609 } 610 mtype = service.method[methodName] 611 if mtype == nil { 612 err = errors.New("rpc: can't find method " + req.ServiceMethod) 613 } 614 return 615 } 616 617 // Accept accepts connections on the listener and serves requests 618 // for each incoming connection. Accept blocks until the listener 619 // returns a non-nil error. The caller typically invokes Accept in a 620 // go statement. 621 func (server *Server) Accept(lis net.Listener) { 622 for { 623 conn, err := lis.Accept() 624 if err != nil { 625 log.Print("rpc.Serve: accept:", err.Error()) 626 return 627 } 628 go server.ServeConn(conn) 629 } 630 } 631 632 // Register publishes the receiver's methods in the DefaultServer. 633 func Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) } 634 635 // RegisterName is like Register but uses the provided name for the type 636 // instead of the receiver's concrete type. 637 func RegisterName(name string, rcvr interface{}) error { 638 return DefaultServer.RegisterName(name, rcvr) 639 } 640 641 // A ServerCodec implements reading of RPC requests and writing of 642 // RPC responses for the server side of an RPC session. 643 // The server calls ReadRequestHeader and ReadRequestBody in pairs 644 // to read requests from the connection, and it calls WriteResponse to 645 // write a response back. The server calls Close when finished with the 646 // connection. ReadRequestBody may be called with a nil 647 // argument to force the body of the request to be read and discarded. 648 type ServerCodec interface { 649 ReadRequestHeader(*Request) error 650 ReadRequestBody(interface{}) error 651 // WriteResponse must be safe for concurrent use by multiple goroutines. 652 WriteResponse(*Response, interface{}) error 653 654 Close() error 655 } 656 657 // ServeConn runs the DefaultServer on a single connection. 658 // ServeConn blocks, serving the connection until the client hangs up. 659 // The caller typically invokes ServeConn in a go statement. 660 // ServeConn uses the gob wire format (see package gob) on the 661 // connection. To use an alternate codec, use ServeCodec. 662 func ServeConn(conn io.ReadWriteCloser) { 663 DefaultServer.ServeConn(conn) 664 } 665 666 // ServeCodec is like ServeConn but uses the specified codec to 667 // decode requests and encode responses. 668 func ServeCodec(codec ServerCodec) { 669 DefaultServer.ServeCodec(codec) 670 } 671 672 // ServeRequest is like ServeCodec but synchronously serves a single request. 673 // It does not close the codec upon completion. 674 func ServeRequest(codec ServerCodec) error { 675 return DefaultServer.ServeRequest(codec) 676 } 677 678 // Accept accepts connections on the listener and serves requests 679 // to DefaultServer for each incoming connection. 680 // Accept blocks; the caller typically invokes it in a go statement. 681 func Accept(lis net.Listener) { DefaultServer.Accept(lis) } 682 683 // Can connect to RPC service using HTTP CONNECT to rpcPath. 684 var connected = "200 Connected to Go RPC" 685 686 // ServeHTTP implements an http.Handler that answers RPC requests. 687 func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { 688 if req.Method != "CONNECT" { 689 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 690 w.WriteHeader(http.StatusMethodNotAllowed) 691 io.WriteString(w, "405 must CONNECT\n") 692 return 693 } 694 conn, _, err := w.(http.Hijacker).Hijack() 695 if err != nil { 696 log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error()) 697 return 698 } 699 io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n") 700 server.ServeConn(conn) 701 } 702 703 // HandleHTTP registers an HTTP handler for RPC messages on rpcPath, 704 // and a debugging handler on debugPath. 705 // It is still necessary to invoke http.Serve(), typically in a go statement. 706 func (server *Server) HandleHTTP(rpcPath, debugPath string) { 707 http.Handle(rpcPath, server) 708 http.Handle(debugPath, debugHTTP{server}) 709 } 710 711 // HandleHTTP registers an HTTP handler for RPC messages to DefaultServer 712 // on DefaultRPCPath and a debugging handler on DefaultDebugPath. 713 // It is still necessary to invoke http.Serve(), typically in a go statement. 714 func HandleHTTP() { 715 DefaultServer.HandleHTTP(DefaultRPCPath, DefaultDebugPath) 716 }