func Client() { var err error var c net.Conn c, err = net.DialTimeout("tcp", "127.0.0.1:1234", 1000*1000*1000*30) if err != nil { log.Fatal("dialing:", err) } var client *rpc.Client client = jsonrpc.NewClient(c) // 同步 var args *Args = &Args{7, 8} var reply *Data = new(Data) client.Call("Arith.Plus", args, reply) fmt.Println(reply) // 异步 args.A = 1 args.B = 2 var call *rpc.Call call = client.Go("Arith.Plus", args, reply, nil) var doneCall *rpc.Call doneCall = <-call.Done fmt.Println(doneCall.Args, doneCall.Reply) fmt.Println(args, reply) client.Close() c.Close() }
func benchmarkEchoProtoRPC(b *testing.B, size int) { var client *rpc.Client benchmarkEcho(b, size, listenAndServeProtoRPC, func(addr net.Addr) { conn, err := tls.Dial(addr.Network(), addr.String(), clientTLSConfig) if err != nil { b.Fatal(err) } client = rpc.NewClientWithCodec(NewClientCodec(conn)) }, func() { if err := client.Close(); err != nil { b.Fatal(err) } }, func(echoMsg string) string { args := EchoRequest{Msg: echoMsg} reply := EchoResponse{} if err := client.Call("Echo.Echo", &args, &reply); err != nil { b.Fatal(err) } return reply.Msg }, ) }
/**@brief helper function for sorting * @param server master storage server addr * @param myhostport trib server's port * @param flags * @return *Libstore * @return error */ func iNewLibstore(server, myhostport string, flags int) (*Libstore, error) { var store Libstore var master *rpc.Client var args storageproto.GetServersArgs var reply storageproto.RegisterReply var err error store.Addr = myhostport store.Flags = flags if store.Addr != "" { rpc.Register(cacherpc.NewCacheRPC(&store)) } lsplog.Vlogf(3, "libstore try to connect to master storage %s", server) master, err = rpc.DialHTTP("tcp", server) if lsplog.CheckReport(1, err) { return nil, err } lsplog.Vlogf(3, "try to call GetServers") master.Call("StorageRPC.GetServers", &args, &reply) if !reply.Ready { for i := 0; i < 5; i++ { time.Sleep(1000 * time.Millisecond) master.Call("StorageRPC.GetServers", &args, &reply) } } err = master.Close() if lsplog.CheckReport(1, err) { lsplog.Vlogf(3, "WARNING close master failed") } // couldn't get list of servers from master if (reply.Ready == false) || (reply.Servers == nil) { return nil, lsplog.MakeErr("Storage system not ready.") } store.Nodes = reply.Servers store.RPCConn = make([]*rpc.Client, len(store.Nodes)) sort.Sort(store.Nodes) /* for i := 0; i < len(store.Nodes); i++ { fmt.Printf("%v\n", store.Nodes[i]) }*/ store.Leases = cache.NewCache() if lsplog.CheckReport(1, err) { return nil, err } lsplog.Vlogf(3, "libstore create complete") return &store, nil }
func (srv *ServerNode) SendPeerMessage(peerName string, api string, args interface{}, reply interface{}) error { srv.lock.RLock() // Find the peer var peer *ServerPeer peer = srv.peers[peerName] srv.lock.RUnlock() if peer == nil { return ERR_PEER_NOT_FOUND } // Attempt to get a connection from the pool //srv_log("Looking for connection in pool for peer %v\n", peerName) var client *rpc.Client var ok bool client, ok = <-peer.connections if !ok { srv_log("Peer %v connection in shutdown - unable to send to peer\n", peerName) return ERR_PEER_NOT_FOUND } //srv_log("Found connection - sending api call %v\n", api) err := client.Call(api, args, reply) if err != nil { srv_log("Error in outbound call to %v - closing client and asking for a new connection: %v\n", peerName, err) client.Close() peer.broken_connections <- struct{}{} } else { //srv_log("Call worked - returning connection to the pool\n") // It worked - restore the connection to the pool peer.connections <- client } return err }
func Client() { var err error var c net.Conn c, err = net.DialTimeout("tcp", "127.0.0.1:9999", 1000*1000*1000*30) if err != nil { log.Fatal("dialing:", err) } var client *rpc.Client client = jsonrpc.NewClient(c) // 同步 var a *PlusA = &PlusA{7, 8} var r *PlusR = new(PlusR) ch := make(chan int) for i := 0; i < 10000; i++ { go func() { client.Call("Test.Plus", a, r) <-ch }() } for j := 0; j < 10000; j++ { ch <- 1 fmt.Println(r) } client.Close() c.Close() }
// putConn adds a connection to the free pool func (r *RPCExt) putConn(c *rpc.Client) { r.mu.Lock() if n := len(r.clients); !r.closed && n < r.maxIdleConnections { r.clients = append(r.clients, c) r.mu.Unlock() return } r.mu.Unlock() c.Close() }
func main() { flag.Parse() args := flag.Args() clientName := args[0] if !strings.Contains(clientName, ":") { clientName = clientName + ":6969" } var client *rpc.Client var err error sleepDuration, _ := time.ParseDuration(fmt.Sprintf("%ds", *interval)) for iter := 0; *numPolls < 0 || iter < *numPolls; iter++ { if iter > 0 { time.Sleep(sleepDuration) } if client == nil { client, err = rpc.DialHTTP("tcp", clientName) if err != nil { fmt.Printf("Error dialing\t%s\n", err) os.Exit(1) } } arg := new(uint64) var reply *httpd.FileSystemHistory err = client.Call("Subd.Poll", arg, &reply) if err != nil { fmt.Printf("Error calling\t%s\n", err) os.Exit(1) } if *newConnection { client.Close() client = nil } fs := reply.FileSystem if fs == nil { fmt.Println("No FileSystem pointer") } else { fs.RebuildPointers() if *debug { fs.DebugWrite(os.Stdout, "") } else { fmt.Print(fs) } if *file != "" { f, err := os.Create(*file) if err != nil { fmt.Printf("Error creating: %s\t%s\n", *file, err) os.Exit(1) } encoder := gob.NewEncoder(f) encoder.Encode(fs) f.Close() } } } }
/* closeBrokenConnection is an internal method to remove broken connections from our cache. */ func (client *Client) closeBrokenConnection(rpcclient *rpc.Client) { client.nodeClientLock.Lock() defer client.nodeClientLock.Unlock() rpcclient.Close() for key, value := range client.nodeClientMap { if value == rpcclient { delete(client.nodeClientMap, key) return } } }
func ApiQuery(w http.ResponseWriter, r *http.Request) { defer func() { //r.Body.Close() }() //_, err := ioutil.ReadAll(r.Body) //if err != nil { // return //} var err error status := make(chan int, 2) go func() { var sock *rpc.Client if sock, err = rpc.DialHTTP("tcp", "localhost:9601"); err != nil { return } defer sock.Close() //r := new(CommandReply) var rsp CommandReply rs := sock.Go("Command.Query", "nil", &rsp, nil) select { case <-rs.Done: status <- 1 case <-time.After(3e9): status <- 9 } //runtime.Goexit() return }() for { select { case <-status: goto L case <-time.After(3e9): goto L } } L: //io.WriteString(w, "{\"status\": \"OK\"}") close(status) return }
func pollSubcommand(client *rpc.Client, args []string) { var err error clientName := fmt.Sprintf("%s:%d", *subHostname, *subPortNum) for iter := 0; *numPolls < 0 || iter < *numPolls; iter++ { if iter > 0 { time.Sleep(time.Duration(*interval) * time.Second) } if client == nil { client, err = rpc.DialHTTP("tcp", clientName) if err != nil { fmt.Printf("Error dialing\t%s\n", err) os.Exit(1) } } var request sub.PollRequest var reply sub.PollResponse pollStartTime := time.Now() err = client.Call("Subd.Poll", request, &reply) fmt.Printf("Poll duration: %s\n", time.Since(pollStartTime)) if err != nil { fmt.Printf("Error calling\t%s\n", err) os.Exit(1) } if *newConnection { client.Close() client = nil } fs := reply.FileSystem if fs == nil { fmt.Println("No FileSystem pointer") } else { fs.RebuildInodePointers() if *debug { fs.DebugWrite(os.Stdout, "") } else { fmt.Print(fs) } if *file != "" { f, err := os.Create(*file) if err != nil { fmt.Printf("Error creating: %s\t%s\n", *file, err) os.Exit(1) } encoder := gob.NewEncoder(f) encoder.Encode(fs) f.Close() } } } time.Sleep(time.Duration(*wait) * time.Second) }
func GetLogTime(uid uint32) (intime, outtime string, err error) { var cli *rpc.Client if cli, err = jsonrpc.Dial("tcp", PY_RPC_ADDR); err != nil { return } defer cli.Close() args := &argUid{uid} reply := new(getLogTimeRep) if err = cli.Call("getLogTime", args, reply); err != nil { return } intime, outtime = reply.Logintime, reply.Logouttime return }
func ModifyBalance(uid uint32, num int32) (balance uint32, err error) { var cli *rpc.Client if cli, err = jsonrpc.Dial("tcp", PY_RPC_ADDR); err != nil { return } defer cli.Close() args := &argModifyBalance{uid, num} reply := new(modifyBalanceRep) if err = cli.Call("modifyBalance", args, reply); err != nil { return } balance = reply.Balance return }
func GetBalance(uids []uint32) (ubl map[uint32]uint32, err error) { var cli *rpc.Client if cli, err = jsonrpc.Dial("tcp", PY_RPC_ADDR); err != nil { return } defer cli.Close() args := &argGetBalance{uids} reply := new(getBalanceRep) if err = cli.Call("getBalance", args, reply); err != nil { return } ubl = reply.keyToUint32() return }
func SetName(uid uint32, name string) (Rname string, err error) { var cli *rpc.Client if cli, err = jsonrpc.Dial("tcp", PY_RPC_ADDR); err != nil { return } defer cli.Close() args := &argSetName{uid, name} reply := new(setNameRep) if cli.Call("setName", args, reply); err != nil { return } Rname = reply.Name return }
func GetBillboard(uid uint32) (ret [][]string, err error) { var cli *rpc.Client if cli, err = jsonrpc.Dial("tcp", PY_RPC_ADDR); err != nil { return } defer cli.Close() args := &argGetBillboard{uid} reply := new(getBillboardRep) if cli.Call("getBillboard", args, reply); err != nil { return } ret = reply.Billboard return }
func SetDayCounter(uid uint32, chip int32) (ret int32, err error) { var cli *rpc.Client if cli, err = jsonrpc.Dial("tcp", PY_RPC_ADDR); err != nil { return } defer cli.Close() args := &argSetDayCounter{uid, chip} reply := new(setDayCounterRep) if cli.Call("setDayCounter", args, reply); err != nil { return } ret = reply.Chip return }
func MakeStore(k *Kademlia, remoteContact *Contact, Key ID, Value []byte) bool { var client *rpc.Client var localContact *Contact var storeReq *StoreRequest var storeRes *StoreResult var remoteAddrStr string var remotePortStr string var err error localContact = &(k.ContactInfo) remoteAddrStr = remoteContact.Host.String() + ":" + strconv.Itoa(int(remoteContact.Port)) dbg.Printf("MakeStore: From %s --> To %s\n", Verbose, localContact.AsString(), remoteContact.AsString()) storeReq = new(StoreRequest) storeReq.MsgID = NewRandomID() storeReq.Sender = CopyContact(localContact) storeReq.Key = CopyID(Key) storeReq.Value = Value storeRes = new(StoreResult) remotePortStr = strconv.Itoa(int(remoteContact.Port)) //Dial the server if RunningTests == true { //if we're running tests, need to DialHTTPPath var portstr string = RpcPath + remotePortStr client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", remoteAddrStr) } if err != nil { Printf("Error: MakeStore, DialHTTP, %s\n", k, Verbose, err) return false } //make the rpc err = client.Call("Kademlia.Store", storeReq, &storeRes) if err != nil { Printf("Error: MakeStore, Call, %s\n", k, Verbose, err) return false } client.Close() //update the remote node contact information k.UpdateChannel <- *remoteContact return true }
func MakePingCall(k *Kademlia, remoteHost net.IP, remotePort uint16) bool { var localContact *Contact var client *rpc.Client var remoteAddrStr string var err error localContact = &(k.ContactInfo) remoteAddrStr = remoteHost.String() + ":" + strconv.FormatUint(uint64(remotePort), 10) Printf("MakePingCall: From %s --> To %s:%d\n", k, Verbose, localContact.AsString(), remoteHost.String(), remotePort) ping := new(Ping) ping.MsgID = NewRandomID() ping.Sender = CopyContact(localContact) pong := new(Pong) //Dial the server if RunningTests == true { var portstr string = RpcPath + strconv.FormatInt(int64(remotePort), 10) Printf("test ping to rpcPath:%s\n", k, Verbose, portstr) client, err = rpc.DialHTTPPath("tcp", remoteAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", remoteAddrStr) } if err != nil { Printf("Error: MakePingCall, DialHTTP, %s\n", k, Verbose, err) return false } //make rpc err = client.Call("Kademlia.Ping", ping, &pong) if err != nil { Printf("Error: MakePingCall, Call, %s\n", k, Verbose, err) return false } client.Close() //log.Printf("About to update with our pong...") //log.Printf("update buffer len: %d\n", len(k.UpdateChannel)) //update the remote node contact information k.UpdateChannel <- pong.Sender //log.Printf("update buffer len: %d\n", len(k.UpdateChannel)) //log.Printf("Stuffed out pong in the channel for the sender...") return true }
/* getRPCClientForNode is an internal method that tries to use the cached rpc instance if it's available. If an instance is not found in the map then a write lock is acquired and a new connection attempted. */ func (client *Client) getRPCClientForNode(nodename string) (*rpc.Client, error) { var rpcclient *rpc.Client var err error client.nodeClientLock.RLock() rpcclient, ok := client.nodeClientMap[nodename] client.nodeClientLock.RUnlock() if ok { return rpcclient, nil } // No already open connection - we need to create one. client.nodeClientLock.Lock() //rpcclient, err = rpc.Dial("tcp", nodename) netconn, err := net.Dial("tcp", nodename) if err != nil { // Error - unable to connect to this node. client.nodeClientLock.Unlock() return nil, err_unable_to_connect_to_node } rpcclient = rpc.NewClient(netconn) //var handlerCodec codec.CborHandle //rpcCodec := codec.GoRpc.ClientCodec(netconn, &handlerCodec) //rpcclient = rpc.NewClientWithCodec(rpcCodec) // Check cluster ID's match args := &rapi.GetClusterDetailsArgs{} reply := &rapi.GetClusterDetailsResults{} err = rpcclient.Call("RPCHandler.GetClusterDetails", args, reply) if err == nil && reply.Result.Code == rapi.RI_SUCCESS { // Check the cluster IDs match if client.clusterID != reply.ClusterID { // This is a serious enough issue that we bail with a fatal error rpcclient.Close() client.nodeClientLock.Unlock() return nil, ErrClusterIdMismatch } // We have a valid connection - store it. client.nodeClientMap[nodename] = rpcclient client.nodeClientLock.Unlock() return rpcclient, nil } // The call failed - so close the connection and return an error rpcclient.Close() client.nodeClientLock.Unlock() return nil, err_unable_to_connect_to_node }
func GetWinner() (t [][]string, y [][]string, err error) { var cli *rpc.Client if cli, err = jsonrpc.Dial("tcp", PY_RPC_ADDR); err != nil { return } defer cli.Close() args := &nullArg{} reply := new(getWinnerRep) if cli.Call("getWinner", args, reply); err != nil { return } t = reply.Today y = reply.Yestoday return }
func setTime(uid uint32, isSetLogout bool) (t string, err error) { var cli *rpc.Client if cli, err = jsonrpc.Dial("tcp", PY_RPC_ADDR); err != nil { return } defer cli.Close() args := &argUid{uid} reply := new(setTimeRep) funcName := "setLoginTime" if isSetLogout { funcName = "setLogoutTime" } if err = cli.Call(funcName, args, reply); err != nil { return } t = reply.Time return }
// helper function to make a RPC call to remote server. // return false if error occurs during Dial or Call. // the function uses Unix rpc call when testing. func paxosAdminCall(srv string, name string, args interface{}, reply interface{}) bool { // c, err := rpc.Dial("unix", srv) var c *rpc.Client var err error c, err = rpc.DialHTTP("tcp", srv) if err != nil { // fmt.Println(err) return false } defer c.Close() err = c.Call(name, args, reply) if err == nil { return true } // fmt.Println(err) return false }
func runclient(cli *rpc.Client) { var args echoproto.Args var reply echoproto.Reply var err, werr error for { // read next token from input fmt.Printf("CLI-SRV: ") _, err = fmt.Scan(&args.V) if err != nil || strings.EqualFold(args.V, "quit") { break } if strings.EqualFold(args.V, "%%") { werr = cli.Call("Server.FetchLog", args, &reply) if werr != nil { break } log.Println("Dumping contents of log.") for i := 0; i < len(reply.Data); i++ { fmt.Printf("%s ", reply.Data[i]) } fmt.Printf("\n") } else { werr = cli.Call("Server.AppendLog", args, &reply) if err != nil { break } fmt.Printf("SRV-CLI: [%s]\n", reply.Data[0]) } } if werr != nil { log.Printf("Lost contact with server: %s\n", werr.Error()) } log.Println("Exiting.") cli.Close() }
//calls the RPC function 'CreateCircuit' on the next DryMartini in the route func MakeCircuitCreateCall(dm *DryMartini, nextNodeAddrStr string, encryptedArray [][]byte) bool { var client *rpc.Client var err error dbg.Printf("MakeCircuitCreateCall: %s\n", Verbose, nextNodeAddrStr) if kademlia.RunningTests == true { //log.Printf("Unimplemented\n") //panic(1) var nextNodePort string = strings.Split(nextNodeAddrStr, ":")[1] if nextNodePort == "" { dbg.Printf("error getting next port: MakeSendCall\n", ERRORS) return false } var portstr string = kademlia.RpcPath + nextNodePort dbg.Printf("test makeCircuitCreateCall to rpcPath:%s\n", Verbose, portstr) client, err = rpc.DialHTTPPath("tcp", nextNodeAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", nextNodeAddrStr) } if err != nil { dbg.Printf("Error: MakeCircuitCreateCall, DialHTTP, %s\n", ERRORS, err) return false } //make rpc var req *CCRequest = new(CCRequest) req.EncryptedData = encryptedArray var res *CCResponse = new(CCResponse) err = client.Call("DryMartini.CreateCircuit", req, res) if err != nil { dbg.Printf("Error: CreateCircuit, Call, %s\n", ERRORS, err) return false } dbg.Printf("got DistributeSymm response: %s:%v\n", Verbose, nextNodeAddrStr, res.Success) client.Close() return res.Success }
//makes a DryMartini.ServeDrink call on address with the Olive data, returning success and returned data if any func MakeSendCall(dataLump Olive, nextNodeAddrStr string) (bool, []byte) { var client *rpc.Client var err error dbg.Printf("MakeSendCall:: next: %s!", Verbose, nextNodeAddrStr) if kademlia.RunningTests == true { //log.Printf("Unimplemented\n") //panic(1) var nextNodePort string = strings.Split(nextNodeAddrStr, ":")[1] if nextNodePort == "" { log.Printf("error getting next port: MakeSendCall\n") panic(1) } var portstr string = kademlia.RpcPath + nextNodePort log.Printf("test MakeSendCall to rpcPath:%s\n", portstr) client, err = rpc.DialHTTPPath("tcp", nextNodeAddrStr, portstr) } else { client, err = rpc.DialHTTP("tcp", nextNodeAddrStr) } if err != nil { log.Printf("Error: MakeSendCall, DialHTTP, %s\n", err) return false, nil } //make rpc var res *ServerResp = new(ServerResp) var req *ServerData = new(ServerData) req.Sent = dataLump err = client.Call("DryMartini.ServeDrink", req, res) if err != nil { log.Printf("Error: SendCall, Call, %s\n", err) return false, nil } dbg.Printf("got SendCall response: %s:%v\n", Verbose, nextNodeAddrStr, res.Success) client.Close() return res.Success, res.Data }
// pingAndRetry ping the rpc connect and re connect when has an error. func (c *Client) pingAndRetry(stop <-chan bool, client *rpc.Client, addr string) { defer func() { if err := client.Close(); err != nil { log.Error("client.Close() error(%v)", err) } }() var ( failed bool status int err error tmp *rpc.Client ) for { select { case <-stop: log.Info("addr: \"%s\" pingAndRetry goroutine exit", addr) return default: } if !failed { if err = client.Call(RPCPing, 0, &status); err != nil { log.Error("client.Call(%s) error(%v)", RPCPing, err) failed = true continue } else { failed = false time.Sleep(rpcClientPingSleep) continue } } if tmp, err = rpc.Dial("tcp", addr); err != nil { log.Error("rpc.Dial(tcp, %s) error(%v)", addr, err) time.Sleep(rpcClientRetrySleep) continue } client = tmp failed = false log.Info("client reconnect %s ok", addr) } }
func durRemoteRater(cd *engine.CallDescriptor) (time.Duration, error) { result := engine.CallCost{} var client *rpc.Client var err error if *json { client, err = jsonrpc.Dial("tcp", *raterAddress) } else { client, err = rpc.Dial("tcp", *raterAddress) } if err != nil { return nilDuration, fmt.Errorf("Could not connect to engine: %s", err.Error()) } defer client.Close() start := time.Now() if *parallel > 0 { // var divCall *rpc.Call var sem = make(chan int, *parallel) var finish = make(chan int) for i := 0; i < *runs; i++ { go func() { sem <- 1 client.Call("Responder.GetCost", cd, &result) <-sem finish <- 1 // divCall = client.Go("Responder.GetCost", cd, &result, nil) }() } for i := 0; i < *runs; i++ { <-finish } // <-divCall.Done } else { for j := 0; j < *runs; j++ { client.Call("Responder.GetCost", cd, &result) } } log.Println(result) return time.Since(start), nil }
// askInput - interacts with the user asking a msisdn number func askInput(c *rpc.Client) (string, error) { reader := bufio.NewReader(os.Stdin) fmt.Print("msisdn: ") input, err := reader.ReadString('\n') if err != nil && err.Error() != io.EOF.Error() { return "", err } // WINDOWS EOF rage. input = strings.Replace(input, "\n", "", -1) input = strings.Replace(input, "\r", "", -1) switch input { case "exit": fmt.Println("\n*** exit ***") _ = c.Close() os.Exit(0) case "help": fmt.Println("enter a MSISDN composed only by digits and optional prefixes (+, 00), 8-15 characters") getRequest(c) } return input, nil }
io_helpers "github.com/cloudfoundry/cli/testhelpers/io" "github.com/codegangsta/cli" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Server", func() { var ( err error client *rpc.Client rpcService *CliRpcService ) AfterEach(func() { if client != nil { client.Close() } }) BeforeEach(func() { rpc.DefaultServer = rpc.NewServer() }) Describe(".NewRpcService", func() { BeforeEach(func() { rpcService, err = NewRpcService(nil, nil, nil, nil) Expect(err).ToNot(HaveOccurred()) }) It("returns an err of another Rpc process is already registered", func() { _, err := NewRpcService(nil, nil, nil, nil)
// PluginRPC returns a type which implements the Plugger interface for making an RPC. // The return type of this class of plugin must be a pointer. // The plugin creates a client per call to allow services to go up-and-down between calls. func PluginRPC(useJSON bool, serviceMethod, endPoint string, ppo ProtoPlugOut) Plugin { if endPoint == "" || serviceMethod == "" || reflect.TypeOf(ppo()).Kind() != reflect.Ptr { return nil } url, err := url.Parse(endPoint) if err != nil { return nil } useTLS := false switch url.Scheme { case "http": endPoint = url.Host case "https": endPoint = url.Host useTLS = true } return func(ctx context.Context, in interface{}) (out interface{}, err error) { var client *rpc.Client var conn *tls.Conn var connClose = func() { if e := conn.Close(); err == nil { err = e } } var errDial error var cfg = &tls.Config{ InsecureSkipVerify: InsecureSkipVerifyTLS, } if useJSON { if useTLS { conn, errDial = tls.Dial("tcp", endPoint, cfg) if errDial == nil { defer connClose() client = jsonrpc.NewClient(conn) } } else { client, errDial = jsonrpc.Dial("tcp", endPoint) } } else { if useTLS { conn, errDial = tls.Dial("tcp", endPoint, cfg) if errDial == nil { defer connClose() client = rpc.NewClient(conn) } } else { client, errDial = rpc.Dial("tcp", endPoint) } } if errDial != nil { return nil, errDial } out = ppo() err = client.Call(serviceMethod, in, out) err2 := client.Close() if err == nil { err = err2 } return } }