src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/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 is a trimmed down version of net/rpc in the standard library.
     7  Original doc:
     8  
     9  Package rpc provides access to the exported methods of an object across a
    10  network or other I/O connection.  A server registers an object, making it visible
    11  as a service with the name of the type of the object.  After registration, exported
    12  methods of the object will be accessible remotely.  A server may register multiple
    13  objects (services) of different types but it is an error to register multiple
    14  objects of the same type.
    15  
    16  Only methods that satisfy these criteria will be made available for remote access;
    17  other methods will be ignored:
    18  
    19    - the method's type is exported.
    20    - the method is exported.
    21    - the method has two arguments, both exported (or builtin) types.
    22    - the method's second argument is a pointer.
    23    - the method has return type error.
    24  
    25  In effect, the method must look schematically like
    26  
    27  	func (t *T) MethodName(argType T1, replyType *T2) error
    28  
    29  where T1 and T2 can be marshaled by encoding/gob.
    30  These requirements apply even if a different codec is used.
    31  (In the future, these requirements may soften for custom codecs.)
    32  
    33  The method's first argument represents the arguments provided by the caller; the
    34  second argument represents the result parameters to be returned to the caller.
    35  The method's return value, if non-nil, is passed back as a string that the client
    36  sees as if created by errors.New.  If an error is returned, the reply parameter
    37  will not be sent back to the client.
    38  
    39  The server may handle requests on a single connection by calling ServeConn.  More
    40  typically it will create a network listener and call Accept or, for an HTTP
    41  listener, HandleHTTP and http.Serve.
    42  
    43  A client wishing to use the service establishes a connection and then invokes
    44  NewClient on the connection.  The convenience function Dial (DialHTTP) performs
    45  both steps for a raw network connection (an HTTP connection).  The resulting
    46  Client object has two methods, Call and Go, that specify the service and method to
    47  call, a pointer containing the arguments, and a pointer to receive the result
    48  parameters.
    49  
    50  The Call method waits for the remote call to complete while the Go method
    51  launches the call asynchronously and signals completion using the Call
    52  structure's Done channel.
    53  
    54  Unless an explicit codec is set up, package encoding/gob is used to
    55  transport the data.
    56  
    57  Here is a simple example.  A server wishes to export an object of type Arith:
    58  
    59  	package server
    60  
    61  	import "errors"
    62  
    63  	type Args struct {
    64  		A, B int
    65  	}
    66  
    67  	type Quotient struct {
    68  		Quo, Rem int
    69  	}
    70  
    71  	type Arith int
    72  
    73  	func (t *Arith) Multiply(args *Args, reply *int) error {
    74  		*reply = args.A * args.B
    75  		return nil
    76  	}
    77  
    78  	func (t *Arith) Divide(args *Args, quo *Quotient) error {
    79  		if args.B == 0 {
    80  			return errors.New("divide by zero")
    81  		}
    82  		quo.Quo = args.A / args.B
    83  		quo.Rem = args.A % args.B
    84  		return nil
    85  	}
    86  
    87  The server calls (for HTTP service):
    88  
    89  	arith := new(Arith)
    90  	rpc.Register(arith)
    91  	rpc.HandleHTTP()
    92  	l, e := net.Listen("tcp", ":1234")
    93  	if e != nil {
    94  		log.Fatal("listen error:", e)
    95  	}
    96  	go http.Serve(l, nil)
    97  
    98  At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
    99  "Arith.Divide".  To invoke one, a client first dials the server:
   100  
   101  	client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
   102  	if err != nil {
   103  		log.Fatal("dialing:", err)
   104  	}
   105  
   106  Then it can make a remote call:
   107  
   108  	// Synchronous call
   109  	args := &server.Args{7,8}
   110  	var reply int
   111  	err = client.Call("Arith.Multiply", args, &reply)
   112  	if err != nil {
   113  		log.Fatal("arith error:", err)
   114  	}
   115  	fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
   116  
   117  or
   118  
   119  	// Asynchronous call
   120  	quotient := new(Quotient)
   121  	divCall := client.Go("Arith.Divide", args, quotient, nil)
   122  	replyCall := <-divCall.Done	// will be equal to divCall
   123  	// check errors, print, etc.
   124  
   125  A server implementation will often provide a simple, type-safe wrapper for the
   126  client.
   127  
   128  The net/rpc package is frozen and is not accepting new features.
   129  */
   130  package rpc
   131  
   132  import (
   133  	"bufio"
   134  	"encoding/gob"
   135  	"errors"
   136  	"go/token"
   137  	"io"
   138  	"log"
   139  	"net"
   140  	"reflect"
   141  	"strings"
   142  	"sync"
   143  )
   144  
   145  // Precompute the reflect type for error. Can't use error directly
   146  // because Typeof takes an empty interface value. This is annoying.
   147  var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
   148  
   149  type methodType struct {
   150  	sync.Mutex // protects counters
   151  	method     reflect.Method
   152  	ArgType    reflect.Type
   153  	ReplyType  reflect.Type
   154  	numCalls   uint
   155  }
   156  
   157  type service struct {
   158  	name   string                 // name of service
   159  	rcvr   reflect.Value          // receiver of methods for the service
   160  	typ    reflect.Type           // type of the receiver
   161  	method map[string]*methodType // registered methods
   162  }
   163  
   164  // Request is a header written before every RPC call. It is used internally
   165  // but documented here as an aid to debugging, such as when analyzing
   166  // network traffic.
   167  type Request struct {
   168  	ServiceMethod string   // format: "Service.Method"
   169  	Seq           uint64   // sequence number chosen by client
   170  	next          *Request // for free list in Server
   171  }
   172  
   173  // Response is a header written before every RPC return. It is used internally
   174  // but documented here as an aid to debugging, such as when analyzing
   175  // network traffic.
   176  type Response struct {
   177  	ServiceMethod string    // echoes that of the Request
   178  	Seq           uint64    // echoes that of the request
   179  	Error         string    // error, if any.
   180  	next          *Response // for free list in Server
   181  }
   182  
   183  // Server represents an RPC Server.
   184  type Server struct {
   185  	serviceMap sync.Map   // map[string]*service
   186  	reqLock    sync.Mutex // protects freeReq
   187  	freeReq    *Request
   188  	respLock   sync.Mutex // protects freeResp
   189  	freeResp   *Response
   190  }
   191  
   192  // NewServer returns a new Server.
   193  func NewServer() *Server {
   194  	return &Server{}
   195  }
   196  
   197  // DefaultServer is the default instance of *Server.
   198  var DefaultServer = NewServer()
   199  
   200  // Is this type exported or a builtin?
   201  func isExportedOrBuiltinType(t reflect.Type) bool {
   202  	for t.Kind() == reflect.Ptr {
   203  		t = t.Elem()
   204  	}
   205  	// PkgPath will be non-empty even for an exported type,
   206  	// so we need to check the type name as well.
   207  	return token.IsExported(t.Name()) || t.PkgPath() == ""
   208  }
   209  
   210  // Register publishes in the server the set of methods of the
   211  // receiver value that satisfy the following conditions:
   212  //   - exported method of exported type
   213  //   - two arguments, both of exported type
   214  //   - the second argument is a pointer
   215  //   - one return value, of type error
   216  //
   217  // It returns an error if the receiver is not an exported type or has
   218  // no suitable methods. It also logs the error using package log.
   219  // The client accesses each method using a string of the form "Type.Method",
   220  // where Type is the receiver's concrete type.
   221  func (server *Server) Register(rcvr any) error {
   222  	return server.register(rcvr, "", false)
   223  }
   224  
   225  // RegisterName is like Register but uses the provided name for the type
   226  // instead of the receiver's concrete type.
   227  func (server *Server) RegisterName(name string, rcvr any) error {
   228  	return server.register(rcvr, name, true)
   229  }
   230  
   231  func (server *Server) register(rcvr any, name string, useName bool) error {
   232  	s := new(service)
   233  	s.typ = reflect.TypeOf(rcvr)
   234  	s.rcvr = reflect.ValueOf(rcvr)
   235  	sname := reflect.Indirect(s.rcvr).Type().Name()
   236  	if useName {
   237  		sname = name
   238  	}
   239  	if sname == "" {
   240  		s := "rpc.Register: no service name for type " + s.typ.String()
   241  		log.Print(s)
   242  		return errors.New(s)
   243  	}
   244  	if !token.IsExported(sname) && !useName {
   245  		s := "rpc.Register: type " + sname + " is not exported"
   246  		log.Print(s)
   247  		return errors.New(s)
   248  	}
   249  	s.name = sname
   250  
   251  	// Install the methods
   252  	s.method = suitableMethods(s.typ, true)
   253  
   254  	if len(s.method) == 0 {
   255  		str := ""
   256  
   257  		// To help the user, see if a pointer receiver would work.
   258  		method := suitableMethods(reflect.PtrTo(s.typ), false)
   259  		if len(method) != 0 {
   260  			str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
   261  		} else {
   262  			str = "rpc.Register: type " + sname + " has no exported methods of suitable type"
   263  		}
   264  		log.Print(str)
   265  		return errors.New(str)
   266  	}
   267  
   268  	if _, dup := server.serviceMap.LoadOrStore(sname, s); dup {
   269  		return errors.New("rpc: service already defined: " + sname)
   270  	}
   271  	return nil
   272  }
   273  
   274  // suitableMethods returns suitable Rpc methods of typ, it will report
   275  // error using log if reportErr is true.
   276  func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType {
   277  	methods := make(map[string]*methodType)
   278  	for m := 0; m < typ.NumMethod(); m++ {
   279  		method := typ.Method(m)
   280  		mtype := method.Type
   281  		mname := method.Name
   282  		// Method must be exported.
   283  		if method.PkgPath != "" {
   284  			continue
   285  		}
   286  		// Method needs three ins: receiver, *args, *reply.
   287  		if mtype.NumIn() != 3 {
   288  			if reportErr {
   289  				log.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname, mtype.NumIn())
   290  			}
   291  			continue
   292  		}
   293  		// First arg need not be a pointer.
   294  		argType := mtype.In(1)
   295  		if !isExportedOrBuiltinType(argType) {
   296  			if reportErr {
   297  				log.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname, argType)
   298  			}
   299  			continue
   300  		}
   301  		// Second arg must be a pointer.
   302  		replyType := mtype.In(2)
   303  		if replyType.Kind() != reflect.Ptr {
   304  			if reportErr {
   305  				log.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname, replyType)
   306  			}
   307  			continue
   308  		}
   309  		// Reply type must be exported.
   310  		if !isExportedOrBuiltinType(replyType) {
   311  			if reportErr {
   312  				log.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname, replyType)
   313  			}
   314  			continue
   315  		}
   316  		// Method needs one out.
   317  		if mtype.NumOut() != 1 {
   318  			if reportErr {
   319  				log.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname, mtype.NumOut())
   320  			}
   321  			continue
   322  		}
   323  		// The return type of the method must be error.
   324  		if returnType := mtype.Out(0); returnType != typeOfError {
   325  			if reportErr {
   326  				log.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname, returnType)
   327  			}
   328  			continue
   329  		}
   330  		methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType}
   331  	}
   332  	return methods
   333  }
   334  
   335  // A value sent as a placeholder for the server's response value when the server
   336  // receives an invalid request. It is never decoded by the client since the Response
   337  // contains an error when it is used.
   338  var invalidRequest = struct{}{}
   339  
   340  func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply any, codec ServerCodec, errmsg string) {
   341  	resp := server.getResponse()
   342  	// Encode the response header
   343  	resp.ServiceMethod = req.ServiceMethod
   344  	if errmsg != "" {
   345  		resp.Error = errmsg
   346  		reply = invalidRequest
   347  	}
   348  	resp.Seq = req.Seq
   349  	sending.Lock()
   350  	err := codec.WriteResponse(resp, reply)
   351  	if debugLog && err != nil {
   352  		log.Println("rpc: writing response:", err)
   353  	}
   354  	sending.Unlock()
   355  	server.freeResponse(resp)
   356  }
   357  
   358  func (m *methodType) NumCalls() (n uint) {
   359  	m.Lock()
   360  	n = m.numCalls
   361  	m.Unlock()
   362  	return n
   363  }
   364  
   365  func (s *service) call(server *Server, sending *sync.Mutex, wg *sync.WaitGroup, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
   366  	if wg != nil {
   367  		defer wg.Done()
   368  	}
   369  	mtype.Lock()
   370  	mtype.numCalls++
   371  	mtype.Unlock()
   372  	function := mtype.method.Func
   373  	// Invoke the method, providing a new value for the reply.
   374  	returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv})
   375  	// The return value for the method is an error.
   376  	errInter := returnValues[0].Interface()
   377  	errmsg := ""
   378  	if errInter != nil {
   379  		errmsg = errInter.(error).Error()
   380  	}
   381  	server.sendResponse(sending, req, replyv.Interface(), codec, errmsg)
   382  	server.freeRequest(req)
   383  }
   384  
   385  type gobServerCodec struct {
   386  	rwc    io.ReadWriteCloser
   387  	dec    *gob.Decoder
   388  	enc    *gob.Encoder
   389  	encBuf *bufio.Writer
   390  	closed bool
   391  }
   392  
   393  func (c *gobServerCodec) ReadRequestHeader(r *Request) error {
   394  	return c.dec.Decode(r)
   395  }
   396  
   397  func (c *gobServerCodec) ReadRequestBody(body any) error {
   398  	return c.dec.Decode(body)
   399  }
   400  
   401  func (c *gobServerCodec) WriteResponse(r *Response, body any) (err error) {
   402  	if err = c.enc.Encode(r); err != nil {
   403  		if c.encBuf.Flush() == nil {
   404  			// Gob couldn't encode the header. Should not happen, so if it does,
   405  			// shut down the connection to signal that the connection is broken.
   406  			log.Println("rpc: gob error encoding response:", err)
   407  			c.Close()
   408  		}
   409  		return
   410  	}
   411  	if err = c.enc.Encode(body); err != nil {
   412  		if c.encBuf.Flush() == nil {
   413  			// Was a gob problem encoding the body but the header has been written.
   414  			// Shut down the connection to signal that the connection is broken.
   415  			log.Println("rpc: gob error encoding body:", err)
   416  			c.Close()
   417  		}
   418  		return
   419  	}
   420  	return c.encBuf.Flush()
   421  }
   422  
   423  func (c *gobServerCodec) Close() error {
   424  	if c.closed {
   425  		// Only call c.rwc.Close once; otherwise the semantics are undefined.
   426  		return nil
   427  	}
   428  	c.closed = true
   429  	return c.rwc.Close()
   430  }
   431  
   432  // ServeConn runs the server on a single connection.
   433  // ServeConn blocks, serving the connection until the client hangs up.
   434  // The caller typically invokes ServeConn in a go statement.
   435  // ServeConn uses the gob wire format (see package gob) on the
   436  // connection. To use an alternate codec, use ServeCodec.
   437  // See NewClient's comment for information about concurrent access.
   438  func (server *Server) ServeConn(conn io.ReadWriteCloser) {
   439  	buf := bufio.NewWriter(conn)
   440  	srv := &gobServerCodec{
   441  		rwc:    conn,
   442  		dec:    gob.NewDecoder(conn),
   443  		enc:    gob.NewEncoder(buf),
   444  		encBuf: buf,
   445  	}
   446  	server.ServeCodec(srv)
   447  }
   448  
   449  // ServeCodec is like ServeConn but uses the specified codec to
   450  // decode requests and encode responses.
   451  func (server *Server) ServeCodec(codec ServerCodec) {
   452  	sending := new(sync.Mutex)
   453  	wg := new(sync.WaitGroup)
   454  	for {
   455  		service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
   456  		if err != nil {
   457  			if debugLog && err != io.EOF {
   458  				log.Println("rpc:", err)
   459  			}
   460  			if !keepReading {
   461  				break
   462  			}
   463  			// send a response if we actually managed to read a header.
   464  			if req != nil {
   465  				server.sendResponse(sending, req, invalidRequest, codec, err.Error())
   466  				server.freeRequest(req)
   467  			}
   468  			continue
   469  		}
   470  		wg.Add(1)
   471  		go service.call(server, sending, wg, mtype, req, argv, replyv, codec)
   472  	}
   473  	// We've seen that there are no more requests.
   474  	// Wait for responses to be sent before closing codec.
   475  	wg.Wait()
   476  	codec.Close()
   477  }
   478  
   479  // ServeRequest is like ServeCodec but synchronously serves a single request.
   480  // It does not close the codec upon completion.
   481  func (server *Server) ServeRequest(codec ServerCodec) error {
   482  	sending := new(sync.Mutex)
   483  	service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
   484  	if err != nil {
   485  		if !keepReading {
   486  			return err
   487  		}
   488  		// send a response if we actually managed to read a header.
   489  		if req != nil {
   490  			server.sendResponse(sending, req, invalidRequest, codec, err.Error())
   491  			server.freeRequest(req)
   492  		}
   493  		return err
   494  	}
   495  	service.call(server, sending, nil, mtype, req, argv, replyv, codec)
   496  	return nil
   497  }
   498  
   499  func (server *Server) getRequest() *Request {
   500  	server.reqLock.Lock()
   501  	req := server.freeReq
   502  	if req == nil {
   503  		req = new(Request)
   504  	} else {
   505  		server.freeReq = req.next
   506  		*req = Request{}
   507  	}
   508  	server.reqLock.Unlock()
   509  	return req
   510  }
   511  
   512  func (server *Server) freeRequest(req *Request) {
   513  	server.reqLock.Lock()
   514  	req.next = server.freeReq
   515  	server.freeReq = req
   516  	server.reqLock.Unlock()
   517  }
   518  
   519  func (server *Server) getResponse() *Response {
   520  	server.respLock.Lock()
   521  	resp := server.freeResp
   522  	if resp == nil {
   523  		resp = new(Response)
   524  	} else {
   525  		server.freeResp = resp.next
   526  		*resp = Response{}
   527  	}
   528  	server.respLock.Unlock()
   529  	return resp
   530  }
   531  
   532  func (server *Server) freeResponse(resp *Response) {
   533  	server.respLock.Lock()
   534  	resp.next = server.freeResp
   535  	server.freeResp = resp
   536  	server.respLock.Unlock()
   537  }
   538  
   539  func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) {
   540  	service, mtype, req, keepReading, err = server.readRequestHeader(codec)
   541  	if err != nil {
   542  		if !keepReading {
   543  			return
   544  		}
   545  		// discard body
   546  		codec.ReadRequestBody(nil)
   547  		return
   548  	}
   549  
   550  	// Decode the argument value.
   551  	argIsValue := false // if true, need to indirect before calling.
   552  	if mtype.ArgType.Kind() == reflect.Ptr {
   553  		argv = reflect.New(mtype.ArgType.Elem())
   554  	} else {
   555  		argv = reflect.New(mtype.ArgType)
   556  		argIsValue = true
   557  	}
   558  	// argv guaranteed to be a pointer now.
   559  	if err = codec.ReadRequestBody(argv.Interface()); err != nil {
   560  		return
   561  	}
   562  	if argIsValue {
   563  		argv = argv.Elem()
   564  	}
   565  
   566  	replyv = reflect.New(mtype.ReplyType.Elem())
   567  
   568  	switch mtype.ReplyType.Elem().Kind() {
   569  	case reflect.Map:
   570  		replyv.Elem().Set(reflect.MakeMap(mtype.ReplyType.Elem()))
   571  	case reflect.Slice:
   572  		replyv.Elem().Set(reflect.MakeSlice(mtype.ReplyType.Elem(), 0, 0))
   573  	}
   574  	return
   575  }
   576  
   577  func (server *Server) readRequestHeader(codec ServerCodec) (svc *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  	svci, ok := server.serviceMap.Load(serviceName)
   604  	if !ok {
   605  		err = errors.New("rpc: can't find service " + req.ServiceMethod)
   606  		return
   607  	}
   608  	svc = svci.(*service)
   609  	mtype = svc.method[methodName]
   610  	if mtype == nil {
   611  		err = errors.New("rpc: can't find method " + req.ServiceMethod)
   612  	}
   613  	return
   614  }
   615  
   616  // Accept accepts connections on the listener and serves requests
   617  // for each incoming connection. Accept blocks until the listener
   618  // returns a non-nil error. The caller typically invokes Accept in a
   619  // go statement.
   620  func (server *Server) Accept(lis net.Listener) {
   621  	for {
   622  		conn, err := lis.Accept()
   623  		if err != nil {
   624  			log.Print("rpc.Serve: accept:", err.Error())
   625  			return
   626  		}
   627  		go server.ServeConn(conn)
   628  	}
   629  }
   630  
   631  // Register publishes the receiver's methods in the DefaultServer.
   632  func Register(rcvr any) error { return DefaultServer.Register(rcvr) }
   633  
   634  // RegisterName is like Register but uses the provided name for the type
   635  // instead of the receiver's concrete type.
   636  func RegisterName(name string, rcvr any) error {
   637  	return DefaultServer.RegisterName(name, rcvr)
   638  }
   639  
   640  // A ServerCodec implements reading of RPC requests and writing of
   641  // RPC responses for the server side of an RPC session.
   642  // The server calls ReadRequestHeader and ReadRequestBody in pairs
   643  // to read requests from the connection, and it calls WriteResponse to
   644  // write a response back. The server calls Close when finished with the
   645  // connection. ReadRequestBody may be called with a nil
   646  // argument to force the body of the request to be read and discarded.
   647  // See NewClient's comment for information about concurrent access.
   648  type ServerCodec interface {
   649  	ReadRequestHeader(*Request) error
   650  	ReadRequestBody(any) error
   651  	WriteResponse(*Response, any) error
   652  
   653  	// Close can be called multiple times and must be idempotent.
   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  // See NewClient's comment for information about concurrent access.
   663  func ServeConn(conn io.ReadWriteCloser) {
   664  	DefaultServer.ServeConn(conn)
   665  }
   666  
   667  // ServeCodec is like ServeConn but uses the specified codec to
   668  // decode requests and encode responses.
   669  func ServeCodec(codec ServerCodec) {
   670  	DefaultServer.ServeCodec(codec)
   671  }
   672  
   673  // ServeRequest is like ServeCodec but synchronously serves a single request.
   674  // It does not close the codec upon completion.
   675  func ServeRequest(codec ServerCodec) error {
   676  	return DefaultServer.ServeRequest(codec)
   677  }
   678  
   679  // Accept accepts connections on the listener and serves requests
   680  // to DefaultServer for each incoming connection.
   681  // Accept blocks; the caller typically invokes it in a go statement.
   682  func Accept(lis net.Listener) { DefaultServer.Accept(lis) }