<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 簡介 golang本身有rpc包,可以方便的使用,來構建自己的rpc服務,下邊是一個簡單是實例,可以加深我們的理解 ![](https://box.kancloud.cn/286674b97311dc901ed172d5a15c481d_538x484.png) 1. 調用客戶端句柄;執行傳送參數 2. 調用本地系統內核發送網絡消息 3. 消息傳送到遠程主機 4. 服務器句柄得到消息并取得參數 5. 執行遠程過程 6. 執行的過程將結果返回服務器句柄 7. 服務器句柄返回結果,調用遠程系統內核 8. 消息傳回本地主機 9. 客戶句柄由內核接收消息 10. 客戶接收句柄返回的數據 `import "net/rpc"` rpc包提供了通過網絡或其他I/O連接對一個對象的導出方法的訪問。**服務端注冊一個對象**,使它作為一個服務被暴露,服務的名字是該對象的類型名。注冊之后,對象的導出方法就可以被遠程訪問。服務端可以注冊多個不同類型的對象(服務),但注冊具有相同類型的多個對象是錯誤的。 **只有滿足如下標準的方法才能用于遠程訪問,其余方法會被忽略:** ~~~ - 方法是導出的 - 方法有兩個參數,都是導出類型或內建類型 - 方法的第二個參數是指針 - 方法只有一個error接口類型的返回值 ~~~ 事實上,方法必須看起來像這樣: ~~~ func (t *T) MethodName(argType T1, replyType *T2) error ~~~ # 測試rpc 服務端,寫方法,注冊rpc ~~~ package main import ( "fmt" "io" "net" "net/http" "net/rpc" ) func pandatext(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "hello world hello panda") } /** - 方法是導出的 - 方法有兩個參數,都是導出類型或內建類型 - 方法的第二個參數是指針 - 方法只有一個error接口類型的返回值 事實上,方法必須看起來像這樣: func (t *T) MethodName(argType T1, replyType *T2) error */ type Panda int //函數關鍵字(對象)函數名(對端發送過來的內容, 返回給對端的內容) 錯誤返回值 func (this *Panda) Getinfo(argType int, replyType *int) error { fmt.Println("打印對端發送過來的內容為: ", argType) //修改內容值 *replyType = argType + 12306 return nil } func main() { //頁面的請求 http.HandleFunc("/panda", pandatext) //需要個對象 pd := new(Panda) //服務端注冊一個對象 rpc.Register(pd) rpc.HandleHTTP() //監聽網絡 ln, err := net.Listen("tcp", ":10086") if err != nil { fmt.Println("網絡錯誤") } http.Serve(ln, nil) } ~~~ 客戶端,連接服務端,發送消息,接收消息 ~~~ import ( "fmt" "net/rpc" ) func main() { //建立網絡連接 cli, err := rpc.DialHTTP("tcp", "127.0.0.1:10086") if err != nil { fmt.Println("---連接錯誤---") } var pd int //rpc服務端對象的方法,發送過去的值,接收變量的指針 e := cli.Call("Panda.Getinfo", 1000, &pd) if e != nil { fmt.Println("---call調用失敗---") } fmt.Println("最后得到的值為: ", pd) } ~~~ # grpc使用protobuf ## 編寫protobuf ~~~ syntax = "proto3"; package myproto; //定義服務 service Helloserver { //一個打招呼的函數 rpc Sayhello(HelloReq) returns (HelloRsp) {} //一個說名字的服務 rpc Sayname(NameReq) returns (NameRsq) {} } //客戶端發送給服務端 message HelloReq { string name = 1; } //服務端返回給客戶端 message HelloRsp { string msg = 1; } //客戶端發送給服務端 message NameReq { string name = 2; } //服務端返回給客戶端 message NameRsq { string msg = 2; } ~~~ 編譯protobuf,用帶grpc插件的方式編譯 ~~~ protoc --go_out=./ *.proto # 不加grpc插件 protoc --go_out=plugins=grpc:./ *.proto # 添加grpc插件 ~~~ ## 編寫服務端 根據protobuf編寫 ~~~ package main import ( "context" "fmt" "google.golang.org/grpc" "net" pd "studygo/myproto" ) /** 復制的 .pd.go文件的 type HelloserverClient interface { //一個打招呼的函數 Sayhello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloRsp, error) //一個說名字的服務 Sayname(ctx context.Context, in *NameReq, opts ...grpc.CallOption) (*NameRsq, error) } */ type server struct{} //rpc //函數關鍵字(對象)函數名(客戶端發送過來的內容 , 返回給客戶端的內容) 錯誤返回值 //grpc //函數關鍵字 (對象)函數名 (cotext,客戶端發過來的參數 )(發送給客戶端的參數,錯誤) //進行改下,綁定到你自己的結構體,參數帶上包名 //一個打招呼的函數 func (this *server) Sayhello(ctx context.Context, in *pd.HelloReq) (out *pd.HelloRsp, err error) { //服務端發送給客戶端,那邊定義的是msg,in.Name,in是參數名,Name是protobuf定義的 fmt.Println("Sayhello客戶端發送過來的: ", in.Name) return &pd.HelloRsp{Msg: "hello"}, nil } //一個說名字的服務 func (this *server) Sayname(ctx context.Context, in *pd.NameReq) (out *pd.NameRsp, err error) { //服務端發送給客戶端,那邊定義的是msg,in.Name,in是參數名,Name是protobuf定義的 fmt.Println("Sayname客戶端發送過來的: ", in.Name) //客戶端發過來的就是in.Name Name就是protobuf那定義的 return &pd.NameRsp{Msg: in.Name + "早上好"}, nil } func main() { //grpc監聽創建網絡 ln, err := net.Listen("tcp", ":10086") if err != nil { fmt.Println("網絡錯誤: ", err) } //創建grpc的服務 srv := grpc.NewServer() //注冊服務 //pd就是protobuf那邊的包,Register后面跟服務名 pd.RegisterHelloserverServer(srv, &server{}) //等待網絡連接 err = srv.Serve(ln) if err != nil { fmt.Println("網絡錯誤: ", err) } } ~~~ 運行起來 ## 編寫客戶端 需要protobuf ~~~ package main import ( "fmt" pd "backend/myproto" "google.golang.org/grpc" "context" ) func main() { //客戶端連接服務器 conn ,err :=grpc.Dial("127.0.0.1:10086",grpc.WithInsecure()) if err != nil { fmt.Println("網絡異常: ", err) } //網絡延遲關閉 defer conn.Close() //獲得grpc句柄 c := pd.NewHelloserverClient(conn) //根據protobuf編寫 //通過句柄調用函數 re, err := c.Sayhello(context.Background(), &pd.HelloReq{Name: "熊貓"}) if err != nil { fmt.Println("sayHello 服務調用失敗") } fmt.Println("調用sayHello的返回", re.Msg) re1, err1 := c.Sayname(context.Background(), &pd.NameReq{Name: "abc"}) if err1 != nil { fmt.Println("sayname 服務調用失敗") } fmt.Println("調用sayname的返回", re1.Msg) } ~~~ 執行下
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看