# yasrpc **Repository Path**: yashan_tech/yasrpc ## Basic Information - **Project Name**: yasrpc - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2025-01-03 - **Last Updated**: 2025-01-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # YasRPC ## 1.注意事项 ### 1.1 服务注册 对 net/rpc 而言,一个函数需要能够被远程调用,需要满足如下五个条件: - 方法所属类型是导出的 - 方法是导出的 - 两个入参,均为导出或内置类型 - 第二个参数必须是一个指针 - 返回值有且只有一个error类型 yasrpc基于net/rpc封装,注册的方法也需要满足以上条件。 例如: ```go func (t *T) MethodName(argType T1, replyType *T2) error // 更加直观一些 func (s *Server) Start(req *Request, resp *Response) error func (s *Server) Wait(req *Request, resp *Response) error func (s *Server) Clean(req *Request, resp *Response) error ``` ## 2.快速开始 ### 2.1 服务注册及调用 Common: ```go // 公共结构体 type Args struct { A, B int } ``` Server: ```go // 注册的服务 type Arith struct{} // 注册的方法 func (t *Arith) Multiply(args *simple.Args, reply *int) error { *reply = args.A * args.B return nil } func main() { arith := new(Arith) // 新建Server实例 svc := yasrpc.NewServer() // 注册服务 if err := svc.Register(arith); err != nil { log.Fatal(err) } // 监听端口 if err := svc.Serve("tcp", "127.0.0.1:5432"); err != nil { log.Fatal(err) } svc.Close() } ``` Client: ```go func main() { // 连接RPC服务 cli, err := yasrpc.Dial("tcp", "127.0.0.1:5432", nil) if err != nil { log.Fatal("client dial error: ", err.Error()) } defer cli.Close() args := &simple.Args{A: 7, B: 8} var reply int ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // 调用注册的方法 if err := cli.Call(ctx, "Arith.Multiply", args, &reply); err != nil { log.Fatal("call Arith.Multiply error:", err) } log.Println("reply: ", reply) } ``` ### 2.2 TLS认证 Server: ```go const ( certPath = "/home/dawn/config/grpc.crt" keyPath = "/home/dawn/config/grpc.key" ) func genTLSConfig() *tls.Config { cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { log.Fatal("tls load error: ", err) } return &tls.Config{Certificates: []tls.Certificate{cert}} } func main() { arith := new(Arith) // 新建带TLS配置的Server实例 svc := yasrpc.NewServer(yasrpc.WithTLSConfig(genTLSConfig())) // 注册服务 if err := svc.Register(arith); err != nil { log.Fatal(err) } // 监听端口 if err := svc.Serve("tcp", "127.0.0.1:5432"); err != nil { log.Fatal(err) } svc.Close() } ``` Client: ```go func genTLSConfig() *tls.Config { b, err := os.ReadFile(certPath) if err != nil { return nil } cp := x509.NewCertPool() if !cp.AppendCertsFromPEM(b) { log.Println("credentials: failed to append certificates") return nil } return &tls.Config{ServerName: "localhost", RootCAs: cp} } func main() { // 连接带TLS认证的RPC服务 cli, err := yasrpc.Dial("tcp", "127.0.0.1:5432", genTLSConfig()) if err != nil { log.Fatal("client dial error: ", err.Error()) } defer cli.Close() args := &simple.Args{A: 7, B: 8} var reply int ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // 调用注册的方法 if err := cli.Call(ctx, "Arith.Multiply", args, &reply); err != nil { log.Fatal("call Arith.Multiply error:", err) } log.Println("reply: ", reply) } ``` ### 2.3 传输文件 Client: Upload file: ```go // Upload file func main() { fileTransferInfo := yasrpc.NewFileTransferInfo(localPath, remotePath) traClient := yasrpc.NewTraClient("tcp", "127.0.0.1:5432", nil, false) err := traClient.UploadFile(context.Background(), fileTransferInfo) if err != nil { log.Fatal("upload file error: ", err) } } ``` Download file: ```go func main() { fileTransferInfo := yasrpc.NewFileTransferInfo(localPath, remotePath) traClient := yasrpc.NewTraClient("tcp", "127.0.0.1:5432", nil, false) err := traClient.DownloadFile(context.Background(), fileTransferInfo) if err != nil { log.Fatal("upload file error: ", err) } } ``` ### 2.4 HTTP Server: ```go type Arith struct{} func (t *Arith) Multiply(args *web.Args, reply *int) error { *reply = args.A * args.B return nil } type LoginForm struct { User string `form:"user" json:"user" binding:"required"` Password string `form:"password" json:"password"` } func main() { arith := new(Arith) svc := yasrpc.NewServer(nil) if err := svc.Register(arith); err != nil { log.Fatal(err) } engine := yasrpc.NewServerEngine(svc) templ := template.Must(template.New("t").Parse(`

Hello Web

`)) engine.SetHTMLTemplate(templ) register(engine) engine.Run("127.0.0.1:5432") } func register(engine *yasrpc.Engine) { engine.GET("/", home) engine.GET("/loginquery", loginquery) engine.POST("/loginform", loginform) engine.POST("/loginjson", loginjson) group1 := engine.Group("/v1", middleware1) group1.GET("/loginquery", loginquery) group1.POST("/loginform", loginform) group1.POST("/loginjson", loginjson) } func middleware1(ctx *yasrpc.Context) { t := time.Now() fmt.Println("start time:", t) ctx.Next() endT := time.Now() fmt.Println("end time:", endT) } func home(ctx *yasrpc.Context) { ctx.HTML(http.StatusOK, "t", "Hello Web") } func loginquery(ctx *yasrpc.Context) { var query LoginForm if err := ctx.BindQuery(&query); err != nil { ctx.JSON(http.StatusBadRequest, yasrpc.H{"error": err.Error()}) return } ctx.String(http.StatusOK, "find user: %v\n", query) } func loginform(ctx *yasrpc.Context) { var query LoginForm if err := ctx.ShouldBindWith(&query, binding.Form); err != nil { ctx.JSON(http.StatusBadRequest, yasrpc.H{"error": err.Error()}) return } ctx.String(http.StatusOK, "find user: %v\n", query) } func loginjson(ctx *yasrpc.Context) { var query LoginForm if err := ctx.BindJSON(&query); err != nil { ctx.JSON(http.StatusBadRequest, yasrpc.H{"error": err.Error()}) return } ctx.JSON(http.StatusOK, yasrpc.H{ "user": query.User, "password": query.Password, }) } ``` client: ```go func main() { opt := &yasrpc.Option{ VerifiedNumber: yasrpc.VerifiedNumber, CodecType: yasrpc.GobType, ConnectTimeout: 10 * time.Second, } cli, err := yasrpc.DialHTTP("tcp", "127.0.0.1:5432", nil, nil, opt) if err != nil { log.DefaultLogger.Fatal("client dial error: ", err.Error()) } defer cli.Close() args := &web.Args{A: 7, B: 8} var reply int ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := cli.Call(ctx, "Arith.Multiply", args, &reply); err != nil { log.DefaultLogger.Info("call Arith.Multiply error:", err) } log.DefaultLogger.Info("reply: ", reply) } ``` Thanks for https://github.com/gin-gonic/gin!