go語言net包rpc遠(yuǎn)程調(diào)用的使用示例

rpc 包提供了一個(gè)方法來通過網(wǎng)絡(luò)或者其他的I/O連接進(jìn)入對(duì)象的外部方法. 一個(gè)server注冊一個(gè)對(duì)象, 標(biāo)記它成為可見對(duì)象類型名字的服務(wù)。注冊后,對(duì)象的外部方法就可以遠(yuǎn)程調(diào)用了。一個(gè)server可以注冊多個(gè) 不同類型的對(duì)象,但是卻不可以注冊多個(gè)相同類型的對(duì)象。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供道外網(wǎng)站建設(shè)、道外做網(wǎng)站、道外網(wǎng)站設(shè)計(jì)、道外網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、道外企業(yè)網(wǎng)站模板建站服務(wù),10年道外做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

只有滿足這些標(biāo)準(zhǔn)的方法才會(huì)被遠(yuǎn)程調(diào)用視為可見;其他的方法都會(huì)被忽略:

- 方法是外部可見的。
- 方法有兩個(gè)參數(shù),參數(shù)的類型都是外部可見的。
- 方法的第二個(gè)參數(shù)是一個(gè)指針。
- 方法有返回類型錯(cuò)誤

一、基于http的RPC

服務(wù)端:

package main;

 

import (

  "net/rpc"

  "net/http"

  "log"

)

 

//go對(duì)RPC的支持,支持三個(gè)級(jí)別:TCP、HTTP、JSONRPC

//go的RPC只支持GO開發(fā)的服務(wù)器與客戶端之間的交互,因?yàn)椴捎昧薵ob編碼

 

//注意字段必須是導(dǎo)出

type Params struct {

  Width, Height int;

}

 

type Rect struct{}

 

//函數(shù)必須是導(dǎo)出的

//必須有兩個(gè)導(dǎo)出類型參數(shù)

//第一個(gè)參數(shù)是接收參數(shù)

//第二個(gè)參數(shù)是返回給客戶端參數(shù),必須是指針類型

//函數(shù)還要有一個(gè)返回值error

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

 

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

 

func main() {

  rect := new(Rect);

  //注冊一個(gè)rect服務(wù)

  rpc.Register(rect);

  //把服務(wù)處理綁定到http協(xié)議上

  rpc.HandleHTTP();

  err := http.ListenAndServe(":8080", nil);

  if err != nil {

    log.Fatal(err);

  }

} 

客戶端:

package main;

 

import (

  "net/rpc"

  "log"

  "fmt"

)

 

type Params struct {

  Width, Height int;

}

 

func main() {

  //連接遠(yuǎn)程rpc服務(wù)

  rpc, err := rpc.DialHTTP("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //調(diào)用遠(yuǎn)程方法

  //注意第三個(gè)參數(shù)是指針類型

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

} 

二、基于tcp的RPC

服務(wù)端:

package main;

 

import (

  "net"

  "log"

  "net/rpc"

)

 

//注意字段必須是導(dǎo)出

type Params struct {

  Width, Height int;

}

 

type Rect struct{}

 

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

 

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

 

func chkError(err error) {

  if err != nil {

    log.Fatal(err);

  }

}

 

func main() {

  rect := new(Rect);

  //注冊rpc服務(wù)

  rpc.Register(rect);

  //獲取tcpaddr

  tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");

  chkError(err);

  //監(jiān)聽端口

  tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);

  chkError(err2);

  //死循環(huán)處理連接請求

  for {

    conn, err3 := tcplisten.Accept();

    if err3 != nil {

      continue;

    }

    //使用goroutine單獨(dú)處理rpc連接請求

    go rpc.ServeConn(conn);

  }

} 

客戶端: 

package main;

 

import (

  "net/rpc"

  "fmt"

  "log"

)

 

type Params struct {

  Width, Height int;

}

 

func main() {

  //連接遠(yuǎn)程rpc服務(wù)

  //這里使用Dial,http方式使用DialHTTP,其他代碼都一樣

  rpc, err := rpc.Dial("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //調(diào)用遠(yuǎn)程方法

  //注意第三個(gè)參數(shù)是指針類型

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

} 

三、JSON RPC 方式

jsonrpc方式是數(shù)據(jù)編碼采用了json,而不是gob編碼。

服務(wù)端:

package main;

 

import (

  "net"

  "log"

  "net/rpc"

  "net/rpc/jsonrpc"

)

 

//注意字段必須是導(dǎo)出

type Params struct {

  Width, Height int;

}

 

type Rect struct{}

 

func (r *Rect) Area(p Params, ret *int) error {

  *ret = p.Width * p.Height;

  return nil;

}

 

func (r *Rect) Perimeter(p Params, ret *int) error {

  *ret = (p.Width + p.Height) * 2;

  return nil;

}

 

func chkError(err error) {

  if err != nil {

    log.Fatal(err);

  }

}

 

func main() {

  rect := new(Rect);

  //注冊rpc服務(wù)

  rpc.Register(rect);

  //獲取tcpaddr

  tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");

  chkError(err);

  //監(jiān)聽端口

  tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);

  chkError(err2);

  for {

    conn, err3 := tcplisten.Accept();

    if err3 != nil {

      continue;

    }

    //使用goroutine單獨(dú)處理rpc連接請求

    //這里使用jsonrpc進(jìn)行處理

    go jsonrpc.ServeConn(conn);

  }

} 

客戶端:

 package main;

 

import (

  "fmt"

  "log"

  "net/rpc/jsonrpc"

)

 

type Params struct {

  Width, Height int;

}

 

func main() {

  //連接遠(yuǎn)程rpc服務(wù)

  //這里使用jsonrpc.Dial

  rpc, err := jsonrpc.Dial("tcp", "127.0.0.1:8080");

  if err != nil {

    log.Fatal(err);

  }

  ret := 0;

  //調(diào)用遠(yuǎn)程方法

  //注意第三個(gè)參數(shù)是指針類型

  err2 := rpc.Call("Rect.Area", Params{50, 100}, &ret);

  if err2 != nil {

    log.Fatal(err2);

  }

  fmt.Println(ret);

  err3 := rpc.Call("Rect.Perimeter", Params{50, 100}, &ret);

  if err3 != nil {

    log.Fatal(err3);

  }

  fmt.Println(ret);

} 

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

網(wǎng)站題目:go語言net包rpc遠(yuǎn)程調(diào)用的使用示例
當(dāng)前路徑:http://muchs.cn/article34/gpjcpe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、手機(jī)網(wǎng)站建設(shè)小程序開發(fā)、網(wǎng)站制作定制開發(fā)、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站