Go語言中的RPC調用


首先,說一下目錄結構:

一、HttpRPC

1、建立服務文件

/*Go RPC的函數只有符合下面的條件才能被遠程訪問,不然會被忽略,詳細的要求如下:
函數必須是導出的(首字母大寫)
必須有兩個導出類型的參數,
第一個參數是接收的參數,第二個參數是返回給客戶端的參數,第二個參數必須是指針類型的
函數還要有一個返回值error
舉個例子,正確的RPC函數格式如下:
func (t *T) MethodName(argType T1, replyType *T2) error
*/
package common

import (
	"errors"
)

type Args struct {
	A, B float32
}
type Result struct {
	Value float32
}
type MathService struct {
}

func (s *MathService) Add(args *Args, result *Result) error {
	result.Value = args.A + args.B
	return nil
}

func (s *MathService) Divide(args *Args, result *Result) error {
	if args.B == 0 {
		return errors.New("除數不能為零!")
	}
	result.Value = args.A / args.B
	return nil
}

  

2、服務端代碼:  

package main

import (
	"fmt"
	"net/http"
	"net/rpc"

	"../common"
)

func main() {
	var ms = new(common.MathService)
	rpc.Register(ms)
	rpc.HandleHTTP() //將Rpc綁定到HTTP協議上。
	fmt.Println("啟動服務...")
	err := http.ListenAndServe(":1234", nil)
	if err != nil {
		fmt.Println(err.Error())
	}
	fmt.Println("服務已停止!")
}

3、客戶端調用代碼:

package main

import (
	"fmt"
	"net/rpc"

	"../common"
)

func main() {
	var args = common.Args{17, 8}
	var result = common.Result{}

	var client, err = rpc.DialHTTP("tcp", "127.0.0.1:1234")
	if err != nil {
		fmt.Println("連接RPC服務失敗:", err)
	}
	err = client.Call("MathService.Divide", args, &result)
	if err != nil {
		fmt.Println("調用失敗:", err)
	}
	fmt.Println("調用結果:", result.Value)
}

4、測試:

 

 

二、HttpRPC

1、建立服務文件

/*Go RPC的函數只有符合下面的條件才能被遠程訪問,不然會被忽略,詳細的要求如下:
函數必須是導出的(首字母大寫)
必須有兩個導出類型的參數,
第一個參數是接收的參數,第二個參數是返回給客戶端的參數,第二個參數必須是指針類型的
函數還要有一個返回值error
舉個例子,正確的RPC函數格式如下:
func (t *T) MethodName(argType T1, replyType *T2) error
*/
package common

import (
	"errors"
)

type Args struct {
	A, B float32
}
type Result struct {
	Value float32
}
type MathService struct {
}

func (s *MathService) Add(args *Args, result *Result) error {
	result.Value = args.A + args.B
	return nil
}

func (s *MathService) Divide(args *Args, result *Result) error {
	if args.B == 0 {
		return errors.New("除數不能為零!")
	}
	result.Value = args.A / args.B
	return nil
}

2、服務端文件

package main

import (
	"fmt"
	"net"
	"net/rpc"

	"../common"
)

func main() {
	var ms = new(common.MathService) //實例化服務對像
	rpc.Register(ms)                 //注冊這個服務
	fmt.Println("啟動服務...")
	var address, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:1234") //定義TCP的服務承載地址
	listener, err := net.ListenTCP("tcp", address)               //監聽TCP連接
	if err != nil {
		fmt.Println("啟動失敗!", err)
	}
	for {
		conn, err := listener.Accept() //如果接受到連接
		if err != nil {
			continue
		}
		fmt.Println("接收到一個調用請求...")
		rpc.ServeConn(conn) //讓此rpc綁定到該Tcp連接上。
	}
	//fmt.Println("服務已停止!")
}

3、客戶端代碼:

// main.go
package main

import (
	"fmt"
	"net/rpc"

	"../common"
)

func main() {
	var client, err = rpc.Dial("tcp", "127.0.0.1:1234")
	if err != nil {
		fmt.Println("連接不到服務器:", err)
	}
	var args = common.Args{40, 3}
	var result = common.Result{}
	fmt.Println("開始調用!")
	err = client.Call("MathService.Add", args, &result)
	if err != nil {
		fmt.Println("調用失敗!", err)
	}
	fmt.Println("調用成功!結果:", result.Value)
}

4、效果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM