@@ -272,7 +272,7 @@ func _new(t *reflect.PtrType) *reflect.PtrValue {
272
272
return v
273
273
}
274
274
275
- func sendResponse (sending * sync.Mutex , req * Request , reply interface {}, enc * gob. Encoder , errmsg string ) {
275
+ func sendResponse (sending * sync.Mutex , req * Request , reply interface {}, codec ServerCodec , errmsg string ) {
276
276
resp := new (Response )
277
277
// Encode the response header
278
278
resp .ServiceMethod = req .ServiceMethod
@@ -281,13 +281,14 @@ func sendResponse(sending *sync.Mutex, req *Request, reply interface{}, enc *gob
281
281
}
282
282
resp .Seq = req .Seq
283
283
sending .Lock ()
284
- enc .Encode (resp )
285
- // Encode the reply value.
286
- enc .Encode (reply )
284
+ err := codec .WriteResponse (resp , reply )
285
+ if err != nil {
286
+ log .Stderr ("rpc: writing response: " , err )
287
+ }
287
288
sending .Unlock ()
288
289
}
289
290
290
- func (s * service ) call (sending * sync.Mutex , mtype * methodType , req * Request , argv , replyv reflect.Value , enc * gob. Encoder ) {
291
+ func (s * service ) call (sending * sync.Mutex , mtype * methodType , req * Request , argv , replyv reflect.Value , codec ServerCodec ) {
291
292
mtype .Lock ()
292
293
mtype .numCalls ++
293
294
mtype .Unlock ()
@@ -300,17 +301,40 @@ func (s *service) call(sending *sync.Mutex, mtype *methodType, req *Request, arg
300
301
if errInter != nil {
301
302
errmsg = errInter .(os.Error ).String ()
302
303
}
303
- sendResponse (sending , req , replyv .Interface (), enc , errmsg )
304
+ sendResponse (sending , req , replyv .Interface (), codec , errmsg )
305
+ }
306
+
307
+ type gobServerCodec struct {
308
+ rwc io.ReadWriteCloser
309
+ dec * gob.Decoder
310
+ enc * gob.Encoder
311
+ }
312
+
313
+ func (c * gobServerCodec ) ReadRequestHeader (r * Request ) os.Error {
314
+ return c .dec .Decode (r )
315
+ }
316
+
317
+ func (c * gobServerCodec ) ReadRequestBody (body interface {}) os.Error {
318
+ return c .dec .Decode (body )
319
+ }
320
+
321
+ func (c * gobServerCodec ) WriteResponse (r * Response , body interface {}) os.Error {
322
+ if err := c .enc .Encode (r ); err != nil {
323
+ return err
324
+ }
325
+ return c .enc .Encode (body )
304
326
}
305
327
306
- func (server * serverType ) input (conn io.ReadWriteCloser ) {
307
- dec := gob .NewDecoder (conn )
308
- enc := gob .NewEncoder (conn )
328
+ func (c * gobServerCodec ) Close () os.Error {
329
+ return c .rwc .Close ()
330
+ }
331
+
332
+ func (server * serverType ) input (codec ServerCodec ) {
309
333
sending := new (sync.Mutex )
310
334
for {
311
335
// Grab the request header.
312
336
req := new (Request )
313
- err := dec . Decode (req )
337
+ err := codec . ReadRequestHeader (req )
314
338
if err != nil {
315
339
if err == os .EOF || err == io .ErrUnexpectedEOF {
316
340
if err == io .ErrUnexpectedEOF {
@@ -319,13 +343,13 @@ func (server *serverType) input(conn io.ReadWriteCloser) {
319
343
break
320
344
}
321
345
s := "rpc: server cannot decode request: " + err .String ()
322
- sendResponse (sending , req , invalidRequest , enc , s )
323
- continue
346
+ sendResponse (sending , req , invalidRequest , codec , s )
347
+ break
324
348
}
325
349
serviceMethod := strings .Split (req .ServiceMethod , "." , 0 )
326
350
if len (serviceMethod ) != 2 {
327
- s := "rpc: service/method request ill: formed: " + req .ServiceMethod
328
- sendResponse (sending , req , invalidRequest , enc , s )
351
+ s := "rpc: service/method request ill- formed: " + req .ServiceMethod
352
+ sendResponse (sending , req , invalidRequest , codec , s )
329
353
continue
330
354
}
331
355
// Look up the request.
@@ -334,27 +358,27 @@ func (server *serverType) input(conn io.ReadWriteCloser) {
334
358
server .Unlock ()
335
359
if ! ok {
336
360
s := "rpc: can't find service " + req .ServiceMethod
337
- sendResponse (sending , req , invalidRequest , enc , s )
361
+ sendResponse (sending , req , invalidRequest , codec , s )
338
362
continue
339
363
}
340
364
mtype , ok := service .method [serviceMethod [1 ]]
341
365
if ! ok {
342
366
s := "rpc: can't find method " + req .ServiceMethod
343
- sendResponse (sending , req , invalidRequest , enc , s )
367
+ sendResponse (sending , req , invalidRequest , codec , s )
344
368
continue
345
369
}
346
370
// Decode the argument value.
347
371
argv := _new (mtype .argType )
348
372
replyv := _new (mtype .replyType )
349
- err = dec . Decode (argv .Interface ())
373
+ err = codec . ReadRequestBody (argv .Interface ())
350
374
if err != nil {
351
375
log .Stderr ("rpc: tearing down" , serviceMethod [0 ], "connection:" , err )
352
- sendResponse (sending , req , replyv .Interface (), enc , err .String ())
353
- continue
376
+ sendResponse (sending , req , replyv .Interface (), codec , err .String ())
377
+ break
354
378
}
355
- go service .call (sending , mtype , req , argv , replyv , enc )
379
+ go service .call (sending , mtype , req , argv , replyv , codec )
356
380
}
357
- conn .Close ()
381
+ codec .Close ()
358
382
}
359
383
360
384
func (server * serverType ) accept (lis net.Listener ) {
@@ -363,7 +387,7 @@ func (server *serverType) accept(lis net.Listener) {
363
387
if err != nil {
364
388
log .Exit ("rpc.Serve: accept:" , err .String ()) // TODO(r): exit?
365
389
}
366
- go server . input (conn )
390
+ go ServeConn (conn )
367
391
}
368
392
}
369
393
@@ -376,10 +400,34 @@ func (server *serverType) accept(lis net.Listener) {
376
400
// suitable methods.
377
401
func Register (rcvr interface {}) os.Error { return server .register (rcvr ) }
378
402
379
- // ServeConn runs the server on a single connection. When the connection
380
- // completes, service terminates. ServeConn blocks; the caller typically
381
- // invokes it in a go statement.
382
- func ServeConn (conn io.ReadWriteCloser ) { server .input (conn ) }
403
+ // A ServerCodec implements reading of RPC requests and writing of
404
+ // RPC responses for the server side of an RPC session.
405
+ // The server calls ReadRequestHeader and ReadRequestBody in pairs
406
+ // to read requests from the connection, and it calls WriteResponse to
407
+ // write a response back. The server calls Close when finished with the
408
+ // connection.
409
+ type ServerCodec interface {
410
+ ReadRequestHeader (* Request ) os.Error
411
+ ReadRequestBody (interface {}) os.Error
412
+ WriteResponse (* Response , interface {}) os.Error
413
+
414
+ Close () os.Error
415
+ }
416
+
417
+ // ServeConn runs the server on a single connection.
418
+ // ServeConn blocks, serving the connection until the client hangs up.
419
+ // The caller typically invokes ServeConn in a go statement.
420
+ // ServeConn uses the gob wire format (see package gob) on the
421
+ // connection. To use an alternate codec, use ServeCodec.
422
+ func ServeConn (conn io.ReadWriteCloser ) {
423
+ ServeCodec (& gobServerCodec {conn , gob .NewDecoder (conn ), gob .NewEncoder (conn )})
424
+ }
425
+
426
+ // ServeCodec is like ServeConn but uses the specified codec to
427
+ // decode requests and encode responses.
428
+ func ServeCodec (codec ServerCodec ) {
429
+ server .input (codec )
430
+ }
383
431
384
432
// Accept accepts connections on the listener and serves requests
385
433
// for each incoming connection. Accept blocks; the caller typically
@@ -404,7 +452,7 @@ func serveHTTP(c *http.Conn, req *http.Request) {
404
452
return
405
453
}
406
454
io .WriteString (conn , "HTTP/1.0 " + connected + "\n \n " )
407
- server . input (conn )
455
+ ServeConn (conn )
408
456
}
409
457
410
458
// HandleHTTP registers an HTTP handler for RPC messages.
0 commit comments