// NewClient makes a netchan connection from the given connection, // imports the rpc service from that, and returns both in a new Client // instance. It assumes that the server has been started with Server. func NewClient(conn io.ReadWriter) (*Client, error) { imp := netchan.NewImporter(conn) srvconn, err := ncnet.Dial(imp, "ncrpc.ctl") if err != nil { return nil, err } return &Client{imp, rpc.NewClient(srvconn)}, nil }
// Serve announces an RPC service on the client using the given name // (which must currently be unique amongst all clients). func (c *Client) Serve(clientName string, rpcServer *rpc.Server) error { var clientId string rpcServer.RegisterName("ClientRPC", clientRPC{}) // TODO better name if err := c.Server.Call("Ncnet-publisher.Publish", &clientName, &clientId); err != nil { return err } clientconn, err := ncnet.Dial(c.Importer, clientId) if err != nil { return err } go rpcServer.ServeConn(clientconn) return nil }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "usage: share [options] tcp-addr\n") flag.PrintDefaults() os.Exit(2) } flag.Parse() if flag.NArg() != 1 { flag.Usage() return } addr := flag.Arg(0) if *server { exp := netchan.NewExporter() if err := exp.ListenAndServe("tcp", addr); err != nil { log.Fatal("listen failed: ", err) } listener, err := ncnet.Listen(exp, "ctl") if err != nil { log.Fatal("ncnet listen failed: ", err) } srv := &Server{ exp: exp, clients: make(map[string]*rpc.Client), } rpcsrv := rpc.NewServer() if err := rpcsrv.Register(srv); err != nil { log.Fatal("rpcsrv register failed: ", err) } rpcsrv.Accept(listener) listener.Close() return } imp, err := netchan.Import("tcp", addr) if err != nil { log.Fatal("netchan import failed: ", err) } srvconn, err := ncnet.Dial(imp, "ctl") if err != nil { log.Fatal("ncnet dial failed: ", err) } srv := rpc.NewClient(srvconn) var clientId string if err := srv.Call("Server.Publish", clientName, &clientId); err != nil { log.Fatal("publish failed: %v", err) } clientsrv := rpc.NewServer() if err := clientsrv.Register(Client{}); err != nil { log.Fatal("clientsrv register failed: ", err) } clientconn, err := ncnet.Dial(imp, clientId) if err != nil { log.Fatalf("ncnet dial %q failed: %v", clientId, err) } go clientsrv.ServeConn(clientconn) interact(srv) clientconn.Close() time.Sleep(0.1e9) // wait for close to propagate }