<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本篇文章旨在通過學習rpc包和github上的一個rpc小專案,熟悉和學習golang中各個包的使用
通過閱讀官方檔案,瞭解了rpc的基本工作模式
第三步第四步中,多次用到的編碼器,是rpc包的關鍵。預設情況下,rpc包使用的是go特有的encoding/gob包進行資料的編碼和解碼。但是當我們伺服器端和使用者端使用了不同的語言時,若加密方法無法相容,就會出現問題,所以rpc包支援自定義編碼器。
go的rpc除了支援常規常規的tpc+埠的遠端呼叫方式,也支援基於http的遠端呼叫實現。但是,我都用rpc了,還用個毛的http形式。不過作為一種形式,我們出於禮貌的簡單瞭解下。
官方檔案的例子,就是使用的http形式的rpc,如下
伺服器端
//範例化rpc遠端呼叫的方法所屬物件 arith := new(Arith) //註冊物件 rpc.Register(arith) //把rpc監聽 對應到http處理器。即指定http請求addr+port時,呼叫的方法 rpc.HandleHTTP() //獲取監聽地址 l, e := net.Listen("tcp", ":1234") if e != nil { log.Fatal("listen error:", e) } //開啟一個go程,持續處理監聽資料 go http.Serve(l, nil)
使用者端
//連線 rpc的http伺服器端 client, err := rpc.DialHTTP("tcp", serverAddress + ":1234") if err != nil { log.Fatal("dialing:", err) } //同步呼叫 // 範例化rpc傳入引數 args := &server.Args{7,8} //宣告rpc 回覆引數。傳入和回覆引數,必須與呼叫方法中的參入型別一致 var reply int //呼叫rpc註冊的方法 err = client.Call("Arith.Multiply", args, &reply) if err != nil { log.Fatal("arith error:", err) } fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply) //或:非同步呼叫 // Asynchronous call quotient := new(Quotient) divCall := client.Go("Arith.Divide", args, quotient, nil) replyCall := <-divCall.Done // will be equal to divCall
從上面的程式碼可以看到,請求伺服器端時,需要使用者端在伺服器發起http請求,如果直接在瀏覽器或者其他工具發起http請求則報錯,因為此時rpc.HandleHTTP方法指定的預設方法,使用的是預設gob編碼器,且只接收connect型別的請求。檢視原始碼,如下
直接發起的http請求,無法使用go獨有的gob包編碼,rpc伺服器端也就無法使用預設gob包解碼。
所以我們要寫一個新的方法代替rpc.HandleHTTp,把http請求繫結到一個使用其他解碼器的方法上,如下
//註冊路由和對應的handler http.HandleFunc("/json", func(rw http.ResponseWriter, r *http.Request) { //宣告一個使用者端連線物件 var conn io.ReadWriteCloser = struct { io.Writer io.ReadCloser }{ ReadCloser: r.Body, Writer: rw, } //也可以使用如下方法獲取接管使用者端連線,http處理器不在管理該連結,使用完畢後需要自行關閉連結 // conn, _, err := rw.(http.Hijacker).Hijack() // if err != nil { // log.Print("rpc hijacking fail: ", err.Error()) // return // } io.WriteString(conn, "HTTP/1.0 rpc-oknn") //server.ServeConn(conn) //rpc.ServeRequest,指定編碼器,以同步的方式處理請求一次,編碼器內不關閉連結,由http服務處理。適用於http形式的請求,因為http是無狀態的,每次請求都是一個新的連結 //rpc.ServeCodec,指定編碼器,for迴圈接收使用者端連結的訊息,每次訊息處理開啟一個go程,相當於非同步處理,直到使用者端關閉或解碼錯誤,跳出迴圈,關閉連線。適用使用者端,一次連線多次傳送資料 rpc.ServeRequest(jsonrpc.NewServerCodec(conn))}) //監聽http請求 http.ListenAndServe("127.0.0.1:1234", nil)
上面程式碼中的==jsonrpc.NewServerCodec(conn)==是一個官方定義好的json格式的編碼器。我們在http中傳送資料時,只要使用json格式,就能被伺服器端解析
執行go檔案,在post模擬url請求,如下
伺服器端
//宣告和註冊rpc方法物件 //獲取監聽資訊 lis, err := net.Listen("tcp", ":8082") if err != nil { log.Fatal(err) } //迴圈讀取監聽到的資料 for { //獲取一個使用者端連線 conn, err := lis.Accept() if err != nil { continue } //開啟一個go程式,使用自定義編碼器處理當前獲取連線 go s.Server.ServeCodec(jsonrpc.NewServerCodec(conn)) }
使用者端
//連線伺服器端 conn, err := net.Dial("tcp", ":8082")if err != nil { log.Fatal(err) } defer conn.Close() //使用json編碼器新建使用者端 client := &Client{rpc.NewClientWithCodec(jsonrpc.NewServerCodec(conn))} //宣告rpc方法中傳入和輸出的引數 resq := message.ArithRequest{A: 20, B: 5} resp := message.ArithResponse{} //呼叫rpc方法 err = client.Call("ArithService.Add", &resq, &resp) log.Printf("Arith.Add(%v, %v): %v ,Error: %v", resq.A, resq.B, resp.C, err)
到此這篇關於golang RPC包原理和使用詳細介紹的文章就介紹到這了,更多相關golang RPC包內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45