25
25
where T, T1 and T2 can be marshaled by encoding/gob.
26
26
These requirements apply even if a different codec is used.
27
(In future, these requirements may soften for custom codecs.)
27
(In the future, these requirements may soften for custom codecs.)
29
29
The method's first argument represents the arguments provided by the caller; the
30
30
second argument represents the result parameters to be returned to the caller.
31
31
The method's return value, if non-nil, is passed back as a string that the client
32
sees as if created by errors.New.
32
sees as if created by errors.New. If an error is returned, the reply parameter
33
will not be sent back to the client.
34
35
The server may handle requests on a single connection by calling ServeConn. More
35
36
typically it will create a network listener and call Accept or, for an HTTP
112
113
// Asynchronous call
113
114
quotient := new(Quotient)
114
divCall := client.Go("Arith.Divide", args, "ient, nil)
115
divCall := client.Go("Arith.Divide", args, quotient, nil)
115
116
replyCall := <-divCall.Done // will be equal to divCall
116
117
// check errors, print, etc.
218
219
// - exported method
219
220
// - two arguments, both pointers to exported structs
220
221
// - one return value, of type error
221
// It returns an error if the receiver is not an exported type or has no
222
// It returns an error if the receiver is not an exported type or has
223
// no methods or unsuitable methods. It also logs the error using package log.
223
224
// The client accesses each method using a string of the form "Type.Method",
224
225
// where Type is the receiver's concrete type.
225
226
func (server *Server) Register(rcvr interface{}) error {
226
227
return server.register(rcvr, "", false)
229
// RegisterName is like Register but uses the provided name for the type
230
// RegisterName is like Register but uses the provided name for the type
230
231
// instead of the receiver's concrete type.
231
232
func (server *Server) RegisterName(name string, rcvr interface{}) error {
232
233
return server.register(rcvr, name, true)
260
261
s.method = make(map[string]*methodType)
262
263
// Install the methods
263
for m := 0; m < s.typ.NumMethod(); m++ {
264
method := s.typ.Method(m)
264
s.method = suitableMethods(s.typ, true)
266
if len(s.method) == 0 {
268
// To help the user, see if a pointer receiver would work.
269
method := suitableMethods(reflect.PtrTo(s.typ), false)
270
if len(method) != 0 {
271
str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
273
str = "rpc.Register: type " + sname + " has no exported methods of suitable type"
276
return errors.New(str)
278
server.serviceMap[s.name] = s
282
// suitableMethods returns suitable Rpc methods of typ, it will report
283
// error using log if reportErr is true.
284
func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType {
285
methods := make(map[string]*methodType)
286
for m := 0; m < typ.NumMethod(); m++ {
287
method := typ.Method(m)
265
288
mtype := method.Type
266
289
mname := method.Name
267
290
// Method must be exported.
271
294
// Method needs three ins: receiver, *args, *reply.
272
295
if mtype.NumIn() != 3 {
273
log.Println("method", mname, "has wrong number of ins:", mtype.NumIn())
297
log.Println("method", mname, "has wrong number of ins:", mtype.NumIn())
276
301
// First arg need not be a pointer.
277
302
argType := mtype.In(1)
278
303
if !isExportedOrBuiltinType(argType) {
279
log.Println(mname, "argument type not exported:", argType)
305
log.Println(mname, "argument type not exported:", argType)
282
309
// Second arg must be a pointer.
283
310
replyType := mtype.In(2)
284
311
if replyType.Kind() != reflect.Ptr {
285
log.Println("method", mname, "reply type not a pointer:", replyType)
313
log.Println("method", mname, "reply type not a pointer:", replyType)
288
317
// Reply type must be exported.
289
318
if !isExportedOrBuiltinType(replyType) {
290
log.Println("method", mname, "reply type not exported:", replyType)
320
log.Println("method", mname, "reply type not exported:", replyType)
293
324
// Method needs one out.
294
325
if mtype.NumOut() != 1 {
295
log.Println("method", mname, "has wrong number of outs:", mtype.NumOut())
327
log.Println("method", mname, "has wrong number of outs:", mtype.NumOut())
298
331
// The return type of the method must be error.
299
332
if returnType := mtype.Out(0); returnType != typeOfError {
300
log.Println("method", mname, "returns", returnType.String(), "not error")
334
log.Println("method", mname, "returns", returnType.String(), "not error")
303
s.method[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType}
306
if len(s.method) == 0 {
307
s := "rpc Register: type " + sname + " has no exported methods of suitable type"
311
server.serviceMap[s.name] = s
338
methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType}
315
343
// A value sent as a placeholder for the server's response value when the server
568
596
// Register publishes the receiver's methods in the DefaultServer.
569
597
func Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) }
571
// RegisterName is like Register but uses the provided name for the type
599
// RegisterName is like Register but uses the provided name for the type
572
600
// instead of the receiver's concrete type.
573
601
func RegisterName(name string, rcvr interface{}) error {
574
602
return DefaultServer.RegisterName(name, rcvr)