Go語言中的RPC調用

首先,說一下目錄結構:服務器

1、HttpRPCtcp

一、創建服務文件ide

/*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
}

  

二、服務端代碼:  函數

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("服務已中止!")
}

三、客戶端調用代碼:測試

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)
}

四、測試:指針

 

 

2、HttpRPCblog

一、創建服務文件rpc

/*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
}

二、服務端文件class

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("服務已中止!")
}

三、客戶端代碼:import

// 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)
}

四、效果:

相關文章
相關標籤/搜索