@@ -272,7 +272,7 @@ func _new(t *reflect.PtrType) *reflect.PtrValue {
272272 return v
273273}
274274
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 ) {
276276 resp := new (Response )
277277 // Encode the response header
278278 resp .ServiceMethod = req .ServiceMethod
@@ -281,13 +281,14 @@ func sendResponse(sending *sync.Mutex, req *Request, reply interface{}, enc *gob
281281 }
282282 resp .Seq = req .Seq
283283 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+ }
287288 sending .Unlock ()
288289}
289290
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 ) {
291292 mtype .Lock ()
292293 mtype .numCalls ++
293294 mtype .Unlock ()
@@ -300,17 +301,40 @@ func (s *service) call(sending *sync.Mutex, mtype *methodType, req *Request, arg
300301 if errInter != nil {
301302 errmsg = errInter .(os.Error ).String ()
302303 }
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 )
304326}
305327
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 ) {
309333 sending := new (sync.Mutex )
310334 for {
311335 // Grab the request header.
312336 req := new (Request )
313- err := dec . Decode (req )
337+ err := codec . ReadRequestHeader (req )
314338 if err != nil {
315339 if err == os .EOF || err == io .ErrUnexpectedEOF {
316340 if err == io .ErrUnexpectedEOF {
@@ -319,13 +343,13 @@ func (server *serverType) input(conn io.ReadWriteCloser) {
319343 break
320344 }
321345 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
324348 }
325349 serviceMethod := strings .Split (req .ServiceMethod , "." , 0 )
326350 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 )
329353 continue
330354 }
331355 // Look up the request.
@@ -334,27 +358,27 @@ func (server *serverType) input(conn io.ReadWriteCloser) {
334358 server .Unlock ()
335359 if ! ok {
336360 s := "rpc: can't find service " + req .ServiceMethod
337- sendResponse (sending , req , invalidRequest , enc , s )
361+ sendResponse (sending , req , invalidRequest , codec , s )
338362 continue
339363 }
340364 mtype , ok := service .method [serviceMethod [1 ]]
341365 if ! ok {
342366 s := "rpc: can't find method " + req .ServiceMethod
343- sendResponse (sending , req , invalidRequest , enc , s )
367+ sendResponse (sending , req , invalidRequest , codec , s )
344368 continue
345369 }
346370 // Decode the argument value.
347371 argv := _new (mtype .argType )
348372 replyv := _new (mtype .replyType )
349- err = dec . Decode (argv .Interface ())
373+ err = codec . ReadRequestBody (argv .Interface ())
350374 if err != nil {
351375 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
354378 }
355- go service .call (sending , mtype , req , argv , replyv , enc )
379+ go service .call (sending , mtype , req , argv , replyv , codec )
356380 }
357- conn .Close ()
381+ codec .Close ()
358382}
359383
360384func (server * serverType ) accept (lis net.Listener ) {
@@ -363,7 +387,7 @@ func (server *serverType) accept(lis net.Listener) {
363387 if err != nil {
364388 log .Exit ("rpc.Serve: accept:" , err .String ()) // TODO(r): exit?
365389 }
366- go server . input (conn )
390+ go ServeConn (conn )
367391 }
368392}
369393
@@ -376,10 +400,34 @@ func (server *serverType) accept(lis net.Listener) {
376400// suitable methods.
377401func Register (rcvr interface {}) os.Error { return server .register (rcvr ) }
378402
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+ }
383431
384432// Accept accepts connections on the listener and serves requests
385433// for each incoming connection. Accept blocks; the caller typically
@@ -404,7 +452,7 @@ func serveHTTP(c *http.Conn, req *http.Request) {
404452 return
405453 }
406454 io .WriteString (conn , "HTTP/1.0 " + connected + "\n \n " )
407- server . input (conn )
455+ ServeConn (conn )
408456}
409457
410458// HandleHTTP registers an HTTP handler for RPC messages.
0 commit comments