栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

GoTips--rpc十分简单示例

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

GoTips--rpc十分简单示例

RPC

Remote Procedure Call Protocol —— 远程过程调用协议!

IPC: 进程间通信

RPC:远程进通信 —— 应用层协议(http协议同层)。底层使用 TCP 实现。

像调用本地函数一样,去调用远程函数

通过rpc协议,传递:函数名、函数参数。达到在本地,调用远端函数,得返回值到本地的目标。

对比: socket通信 server端:

​ net.Listen() —— listener 创建监听器

​ listener.Accpet() —— conn 启动监听,建立连接

​ conn.Read()

​ conn.Write()

​ defer conn.Close() / listener.Close()

client端:

​ net.Dial() —— conn

​ conn.Write()

​ conn.Read()

​ defer conn.Close()

RPC 步骤 ---- 服务端:
  1. 注册 rpc 服务对象。给对象绑定方法( 1. 定义类, 2. 绑定类方法 )

    rpc.RegisterName("服务名",回调对象)
    
  2. 创建监听器

    listener, err := net.Listen()
    
  3. 建立连接

    conn, err := listener.Accept()
    
  4. 将连接 绑定 rpc 服务。

    rpc.ServeConn(conn)
    
---- 客户端:
  1. 用 rpc 连接服务器。

    conn, err := rpc.Dial()
    
  2. 调用远程函数。

    conn.Call("服务名.方法名", 传入参数, 传出参数)
    
RPC相关函数 注册 rpc 服务
func (server *Server) RegisterName(name string, rcvr interface{}) error

参数1:服务名。字符串类型

参数2:对应的rpc对象。该对象绑定的方法要满足:

​ 方法必须是包外可见,即首字母大写。

​ 方法有两个参数,都i是导出类型(strcut、自定义切片之类的)、内建类型

​ 方法的第二个参数,必须为指针(传出参数)

​ 方法只有一个error接口类型的 返回值

举例:

type ZZT stuct {
}		
func (this *ZZT) HelloZZT (name string, resp *string) error { 
}
rpc.RegisterName("服务名,什么都可以", new(ZZT))
绑定rpc服务
func (server *Server) ServeConn(conn io.ReadWriteCloser)
conn: 成功建立好连接的 socket —— conn
调用远程函数
func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error

serviceMethod: “服务名.方法名”
args: 传入参数。 方法需要的数据。
reply: 传出参数。定义 var 变量,&变量名 完成传参。

简易实现:
package main

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

//定义类对象
type Fy struct {
}

//类方法
func (this *Fy) HelloWorld(name string, resp *string) error {
	*resp = name + "你好吖"
	return nil
}
func main() {

	//注册RPC服务,绑定对象方法
	err := rpc.RegisterName("ZZT", new(Fy))
	if err != nil {
		fmt.Println("RPC服务注册失败")
		return
	}
	//设置监听
	listener, err := net.Listen("tcp", "127.0.0.1:9876")
	if err != nil {
		fmt.Println("Listen err:", err)
		return
	}
	fmt.Println("开始监听")
	defer listener.Close()

	//建立连接
	conn, err := listener.Accept()
	if err != nil {
		fmt.Println("Accept err:", err)
		return
	}
	fmt.Println("建立连接")
	defer conn.Close()

	//绑定服务
	rpc.ServeConn(conn)
	fmt.Println("服务绑定")

}

package main

import (
	"fmt"
	"net/rpc"
)

func main() {
	//用rpc连接服务器
	conn, err := rpc.Dial("tcp", "127.0.0.1:9876")
	if err != nil {
		fmt.Println("Dial err:", err)
		return
	}
	fmt.Println("连接上服务器")
	//调用远程函数(服务名.方法名)
	var reply string
	err = conn.Call("ZZT.HelloWorld", "奥里给", &reply)
	if err != nil {
		fmt.Println("Call err ", err)
		return
	}
	fmt.Println(reply)
}

rpc 封装 服务端封装
  1. // 定义接口
    type xxx interface {
        方法名(传入参数,传出参数) error
    }
    例:
    type MyInterface interface {
        HelloWorld(string, *string) error
    }
    
  2. // 封装注册服务方法
    func RegisterService (i MyInterface) {
        rpc.RegisterName("hello", i)
    }
    
客户端封装
  1. // 定义类
    type MyClient struct {
        c *rpc.Client
    }
    
  2. // 绑定类方法
    func (this *MyClient)HelloWorld(a string, b *string) error {
       return  this.c.Call("hello.HelloWorld", a, b)
    }
    
  3. // 初始客户端
    func InitClient(addr string) error {
        conn, _ := jsonrpc.Dial("tcp", adddr)
        return MyClient{c:conn}
    }
    
笔记参考
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/990313.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号