github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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 serviceMap sync.Map // map[string]*service 191 reqLock sync.Mutex // protects freeReq 192 freeReq *Request 193 respLock sync.Mutex // protects freeResp 194 freeResp *Response 195 } 196 197 // NewServer returns a new Server. 198 func NewServer() *Server { 199 return &Server{} 200 } 201 202 // DefaultServer is the default instance of *Server. 203 var DefaultServer = NewServer() 204 205 // Is this an exported - upper case - name? 206 func isExported(name string) bool { 207 rune, _ := utf8.DecodeRuneInString(name) 208 return unicode.IsUpper(rune) 209 } 210 211 // Is this type exported or a builtin? 212 func isExportedOrBuiltinType(t reflect.Type) bool { 213 for t.Kind() == reflect.Ptr { 214 t = t.Elem() 215 } 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() == "" 219 } 220 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) 233 } 234 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) 239 } 240 241 func (server *Server) register(rcvr interface{}, name string, useName bool) error { 242 s := new(service) 243 s.typ = reflect.TypeOf(rcvr) 244 s.rcvr = reflect.ValueOf(rcvr) 245 sname := reflect.Indirect(s.rcvr).Type().Name() 246 if useName { 247 sname = name 248 } 249 if sname == "" { 250 s := "rpc.Register: no service name for type " + s.typ.String() 251 log.Print(s) 252 return errors.New(s) 253 } 254 if !isExported(sname) && !useName { 255 s := "rpc.Register: type " + sname + " is not exported" 256 log.Print(s) 257 return errors.New(s) 258 } 259 s.name = sname 260 261 // Install the methods 262 s.method = suitableMethods(s.typ, true) 263 264 if len(s.method) == 0 { 265 str := "" 266 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)" 271 } else { 272 str = "rpc.Register: type " + sname + " has no exported methods of suitable type" 273 } 274 log.Print(str) 275 return errors.New(str) 276 } 277 278 if _, dup := server.serviceMap.LoadOrStore(sname, s); dup { 279 return errors.New("rpc: service already defined: " + sname) 280 } 281 return nil 282 } 283 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) 290 mtype := method.Type 291 mname := method.Name 292 // Method must be exported. 293 if method.PkgPath != "" { 294 continue 295 } 296 // Method needs three ins: receiver, *args, *reply. 297 if mtype.NumIn() != 3 { 298 if reportErr { 299 log.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname, mtype.NumIn()) 300 } 301 continue 302 } 303 // First arg need not be a pointer. 304 argType := mtype.In(1) 305 if !isExportedOrBuiltinType(argType) { 306 if reportErr { 307 log.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname, argType) 308 } 309 continue 310 } 311 // Second arg must be a pointer. 312 replyType := mtype.In(2) 313 if replyType.Kind() != reflect.Ptr { 314 if reportErr { 315 log.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname, replyType) 316 } 317 continue 318 } 319 // Reply type must be exported. 320 if !isExportedOrBuiltinType(replyType) { 321 if reportErr { 322 log.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname, replyType) 323 } 324 continue 325 } 326 // Method needs one out. 327 if mtype.NumOut() != 1 { 328 if reportErr { 329 log.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname, mtype.NumOut()) 330 } 331 continue 332 } 333 // The return type of the method must be error. 334 if returnType := mtype.Out(0); returnType != typeOfError { 335 if reportErr { 336 log.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname, returnType) 337 } 338 continue 339 } 340 methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType} 341 } 342 return methods 343 } 344 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{}{} 349 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 354 if errmsg != "" { 355 resp.Error = errmsg 356 reply = invalidRequest 357 } 358 resp.Seq = req.Seq 359 sending.Lock() 360 err := codec.WriteResponse(resp, reply) 361 if debugLog && err != nil { 362 log.Println("rpc: writing response:", err) 363 } 364 sending.Unlock() 365 server.freeResponse(resp) 366 } 367 368 func (m *methodType) NumCalls() (n uint) { 369 m.Lock() 370 n = m.numCalls 371 m.Unlock() 372 return n 373 } 374 375 func (s *service) call(server *Server, sending *sync.Mutex, wg *sync.WaitGroup, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) { 376 if wg != nil { 377 defer wg.Done() 378 } 379 mtype.Lock() 380 mtype.numCalls++ 381 mtype.Unlock() 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() 387 errmsg := "" 388 if errInter != nil { 389 errmsg = errInter.(error).Error() 390 } 391 server.sendResponse(sending, req, replyv.Interface(), codec, errmsg) 392 server.freeRequest(req) 393 } 394 395 type gobServerCodec struct { 396 rwc io.ReadWriteCloser 397 dec *gob.Decoder 398 enc *gob.Encoder 399 encBuf *bufio.Writer 400 closed bool 401 } 402 403 func (c *gobServerCodec) ReadRequestHeader(r *Request) error { 404 return c.dec.Decode(r) 405 } 406 407 func (c *gobServerCodec) ReadRequestBody(body interface{}) error { 408 return c.dec.Decode(body) 409 } 410 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) 417 c.Close() 418 } 419 return 420 } 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) 426 c.Close() 427 } 428 return 429 } 430 return c.encBuf.Flush() 431 } 432 433 func (c *gobServerCodec) Close() error { 434 if c.closed { 435 // Only call c.rwc.Close once; otherwise the semantics are undefined. 436 return nil 437 } 438 c.closed = true 439 return c.rwc.Close() 440 } 441 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 // See NewClient's comment for information about concurrent access. 448 func (server *Server) ServeConn(conn io.ReadWriteCloser) { 449 buf := bufio.NewWriter(conn) 450 srv := &gobServerCodec{ 451 rwc: conn, 452 dec: gob.NewDecoder(conn), 453 enc: gob.NewEncoder(buf), 454 encBuf: buf, 455 } 456 server.ServeCodec(srv) 457 } 458 459 // ServeCodec is like ServeConn but uses the specified codec to 460 // decode requests and encode responses. 461 func (server *Server) ServeCodec(codec ServerCodec) { 462 sending := new(sync.Mutex) 463 wg := new(sync.WaitGroup) 464 for { 465 service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec) 466 if err != nil { 467 if debugLog && err != io.EOF { 468 log.Println("rpc:", err) 469 } 470 if !keepReading { 471 break 472 } 473 // send a response if we actually managed to read a header. 474 if req != nil { 475 server.sendResponse(sending, req, invalidRequest, codec, err.Error()) 476 server.freeRequest(req) 477 } 478 continue 479 } 480 wg.Add(1) 481 go service.call(server, sending, wg, mtype, req, argv, replyv, codec) 482 } 483 // We've seen that there are no more requests. 484 // Wait for responses to be sent before closing codec. 485 wg.Wait() 486 codec.Close() 487 } 488 489 // ServeRequest is like ServeCodec but synchronously serves a single request. 490 // It does not close the codec upon completion. 491 func (server *Server) ServeRequest(codec ServerCodec) error { 492 sending := new(sync.Mutex) 493 service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec) 494 if err != nil { 495 if !keepReading { 496 return err 497 } 498 // send a response if we actually managed to read a header. 499 if req != nil { 500 server.sendResponse(sending, req, invalidRequest, codec, err.Error()) 501 server.freeRequest(req) 502 } 503 return err 504 } 505 service.call(server, sending, nil, mtype, req, argv, replyv, codec) 506 return nil 507 } 508 509 func (server *Server) getRequest() *Request { 510 server.reqLock.Lock() 511 req := server.freeReq 512 if req == nil { 513 req = new(Request) 514 } else { 515 server.freeReq = req.next 516 *req = Request{} 517 } 518 server.reqLock.Unlock() 519 return req 520 } 521 522 func (server *Server) freeRequest(req *Request) { 523 server.reqLock.Lock() 524 req.next = server.freeReq 525 server.freeReq = req 526 server.reqLock.Unlock() 527 } 528 529 func (server *Server) getResponse() *Response { 530 server.respLock.Lock() 531 resp := server.freeResp 532 if resp == nil { 533 resp = new(Response) 534 } else { 535 server.freeResp = resp.next 536 *resp = Response{} 537 } 538 server.respLock.Unlock() 539 return resp 540 } 541 542 func (server *Server) freeResponse(resp *Response) { 543 server.respLock.Lock() 544 resp.next = server.freeResp 545 server.freeResp = resp 546 server.respLock.Unlock() 547 } 548 549 func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) { 550 service, mtype, req, keepReading, err = server.readRequestHeader(codec) 551 if err != nil { 552 if !keepReading { 553 return 554 } 555 // discard body 556 codec.ReadRequestBody(nil) 557 return 558 } 559 560 // Decode the argument value. 561 argIsValue := false // if true, need to indirect before calling. 562 if mtype.ArgType.Kind() == reflect.Ptr { 563 argv = reflect.New(mtype.ArgType.Elem()) 564 } else { 565 argv = reflect.New(mtype.ArgType) 566 argIsValue = true 567 } 568 // argv guaranteed to be a pointer now. 569 if err = codec.ReadRequestBody(argv.Interface()); err != nil { 570 return 571 } 572 if argIsValue { 573 argv = argv.Elem() 574 } 575 576 replyv = reflect.New(mtype.ReplyType.Elem()) 577 578 switch mtype.ReplyType.Elem().Kind() { 579 case reflect.Map: 580 replyv.Elem().Set(reflect.MakeMap(mtype.ReplyType.Elem())) 581 case reflect.Slice: 582 replyv.Elem().Set(reflect.MakeSlice(mtype.ReplyType.Elem(), 0, 0)) 583 } 584 return 585 } 586 587 func (server *Server) readRequestHeader(codec ServerCodec) (svc *service, mtype *methodType, req *Request, keepReading bool, err error) { 588 // Grab the request header. 589 req = server.getRequest() 590 err = codec.ReadRequestHeader(req) 591 if err != nil { 592 req = nil 593 if err == io.EOF || err == io.ErrUnexpectedEOF { 594 return 595 } 596 err = errors.New("rpc: server cannot decode request: " + err.Error()) 597 return 598 } 599 600 // We read the header successfully. If we see an error now, 601 // we can still recover and move on to the next request. 602 keepReading = true 603 604 dot := strings.LastIndex(req.ServiceMethod, ".") 605 if dot < 0 { 606 err = errors.New("rpc: service/method request ill-formed: " + req.ServiceMethod) 607 return 608 } 609 serviceName := req.ServiceMethod[:dot] 610 methodName := req.ServiceMethod[dot+1:] 611 612 // Look up the request. 613 svci, ok := server.serviceMap.Load(serviceName) 614 if !ok { 615 err = errors.New("rpc: can't find service " + req.ServiceMethod) 616 return 617 } 618 svc = svci.(*service) 619 mtype = svc.method[methodName] 620 if mtype == nil { 621 err = errors.New("rpc: can't find method " + req.ServiceMethod) 622 } 623 return 624 } 625 626 // Accept accepts connections on the listener and serves requests 627 // for each incoming connection. Accept blocks until the listener 628 // returns a non-nil error. The caller typically invokes Accept in a 629 // go statement. 630 func (server *Server) Accept(lis net.Listener) { 631 for { 632 conn, err := lis.Accept() 633 if err != nil { 634 log.Print("rpc.Serve: accept:", err.Error()) 635 return 636 } 637 go server.ServeConn(conn) 638 } 639 } 640 641 // Register publishes the receiver's methods in the DefaultServer. 642 func Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) } 643 644 // RegisterName is like Register but uses the provided name for the type 645 // instead of the receiver's concrete type. 646 func RegisterName(name string, rcvr interface{}) error { 647 return DefaultServer.RegisterName(name, rcvr) 648 } 649 650 // A ServerCodec implements reading of RPC requests and writing of 651 // RPC responses for the server side of an RPC session. 652 // The server calls ReadRequestHeader and ReadRequestBody in pairs 653 // to read requests from the connection, and it calls WriteResponse to 654 // write a response back. The server calls Close when finished with the 655 // connection. ReadRequestBody may be called with a nil 656 // argument to force the body of the request to be read and discarded. 657 // See NewClient's comment for information about concurrent access. 658 type ServerCodec interface { 659 ReadRequestHeader(*Request) error 660 ReadRequestBody(interface{}) error 661 WriteResponse(*Response, interface{}) error 662 663 // Close can be called multiple times and must be idempotent. 664 Close() error 665 } 666 667 // ServeConn runs the DefaultServer on a single connection. 668 // ServeConn blocks, serving the connection until the client hangs up. 669 // The caller typically invokes ServeConn in a go statement. 670 // ServeConn uses the gob wire format (see package gob) on the 671 // connection. To use an alternate codec, use ServeCodec. 672 // See NewClient's comment for information about concurrent access. 673 func ServeConn(conn io.ReadWriteCloser) { 674 DefaultServer.ServeConn(conn) 675 } 676 677 // ServeCodec is like ServeConn but uses the specified codec to 678 // decode requests and encode responses. 679 func ServeCodec(codec ServerCodec) { 680 DefaultServer.ServeCodec(codec) 681 } 682 683 // ServeRequest is like ServeCodec but synchronously serves a single request. 684 // It does not close the codec upon completion. 685 func ServeRequest(codec ServerCodec) error { 686 return DefaultServer.ServeRequest(codec) 687 } 688 689 // Accept accepts connections on the listener and serves requests 690 // to DefaultServer for each incoming connection. 691 // Accept blocks; the caller typically invokes it in a go statement. 692 func Accept(lis net.Listener) { DefaultServer.Accept(lis) } 693 694 // Can connect to RPC service using HTTP CONNECT to rpcPath. 695 var connected = "200 Connected to Go RPC" 696 697 // ServeHTTP implements an http.Handler that answers RPC requests. 698 func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { 699 if req.Method != "CONNECT" { 700 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 701 w.WriteHeader(http.StatusMethodNotAllowed) 702 io.WriteString(w, "405 must CONNECT\n") 703 return 704 } 705 conn, _, err := w.(http.Hijacker).Hijack() 706 if err != nil { 707 log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error()) 708 return 709 } 710 io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n") 711 server.ServeConn(conn) 712 } 713 714 // HandleHTTP registers an HTTP handler for RPC messages on rpcPath, 715 // and a debugging handler on debugPath. 716 // It is still necessary to invoke http.Serve(), typically in a go statement. 717 func (server *Server) HandleHTTP(rpcPath, debugPath string) { 718 http.Handle(rpcPath, server) 719 http.Handle(debugPath, debugHTTP{server}) 720 } 721 722 // HandleHTTP registers an HTTP handler for RPC messages to DefaultServer 723 // on DefaultRPCPath and a debugging handler on DefaultDebugPath. 724 // It is still necessary to invoke http.Serve(), typically in a go statement. 725 func HandleHTTP() { 726 DefaultServer.HandleHTTP(DefaultRPCPath, DefaultDebugPath) 727 }