// HandleHTTP registers an HTTP handler for RPC messages on rpcPath. // It is still necessary to invoke http.Serve(), typically in a go statement. func(server *Server) HandleHTTP() { http.Handle(defaultRPCPath, server) }
// HandleHTTP is a convenient approach for default server to register HTTP handlers funcHandleHTTP() { DefaultServer.HandleHTTP() }
在 Go 语言中处理 HTTP 请求是非常简单的一件事,Go 标准库中 http.Handle 的实现如下:
1 2 3 4 5 6
package http // Handle registers the handler for the given pattern // in the DefaultServeMux. // The documentation for ServeMux explains how patterns are matched. funcHandle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
第一个参数pattern是支持通配的字符串,我们固定传入 /_geeprc_
第二个参数Handler 是一个接口
1 2 3
type Handler interface { ServeHTTP(w ResponseWriter, r *Request) }
// DialHTTP connects to an HTTP RPC server at the specified network address // listening on the default HTTP RPC path. funcDialHTTP(network, address string, opts ...*Option) (*Client, error) { return dialTimeout(NewHTTPClient, network, address, opts...) }
为了简化调用,我们封装一个xdial方法,该方法会检测请求体的第一个参数
如果是http就使用我们写好的方法,如果是其他就调用go net包下的dial方法来处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// XDial calls different functions to connect to a RPC server // according the first parameter rpcAddr. // rpcAddr is a general format (protocol@addr) to represent a rpc server // eg, http@10.0.0.1:7001, tcp@10.0.0.1:9999, unix@/tmp/geerpc.sock funcXDial(rpcAddr string, opts ...*Option) (*Client, error) { parts := strings.Split(rpcAddr, "@") iflen(parts) != 2 { returnnil, fmt.Errorf("rpc client err: wrong format '%s', expect protocol@addr", rpcAddr) } protocol, addr := parts[0], parts[1] switch protocol { case"http": return DialHTTP("tcp", addr, opts...) default: // tcp, unix or other transport protocol return Dial(protocol, addr, opts...) } }