posts - 404,  comments - 115,  views - 118万
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

一、基于http的RPC

服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package main;
 
import (
    "net/rpc"
    "net/http"
    "log"
)
 
//go对RPC的支持,支持三个级别:TCP、HTTP、JSONRPC
//go的RPC只支持GO开发的服务器与客户端之间的交互,因为采用了gob编码
 
//注意字段必须是导出
type Params struct {
    Width, Height int;
}
 
type Rect struct{}
 
//函数必须是导出的
//必须有两个导出类型参数
//第一个参数是接收参数
//第二个参数是返回给客户端参数,必须是指针类型
//函数还要有一个返回值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);
    //注册一个rect服务
    rpc.Register(rect);
    //把服务处理绑定到http协议上
    rpc.HandleHTTP();
    err := http.ListenAndServe(":8080", nil);
    if err != nil {
        log.Fatal(err);
    }
}

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main;
 
import (
    "net/rpc"
    "log"
    "fmt"
)
 
type Params struct {
    Width, Height int;
}
 
func main() {
    //连接远程rpc服务
    rpc, err := rpc.DialHTTP("tcp", "127.0.0.1:8080");
    if err != nil {
        log.Fatal(err);
    }
    ret := 0;
    //调用远程方法
    //注意第三个参数是指针类型
    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

服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package main;
 
import (
    "net"
    "log"
    "net/rpc"
)
 
//注意字段必须是导出
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服务
    rpc.Register(rect);
    //获取tcpaddr
    tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
    chkError(err);
    //监听端口
    tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
    chkError(err2);
    //死循环处理连接请求
    for {
        conn, err3 := tcplisten.Accept();
        if err3 != nil {
            continue;
        }
        //使用goroutine单独处理rpc连接请求
        go rpc.ServeConn(conn);
    }
}

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main;
 
import (
    "net/rpc"
    "fmt"
    "log"
)
 
type Params struct {
    Width, Height int;
}
 
func main() {
    //连接远程rpc服务
    //这里使用Dial,http方式使用DialHTTP,其他代码都一样
    rpc, err := rpc.Dial("tcp", "127.0.0.1:8080");
    if err != nil {
        log.Fatal(err);
    }
    ret := 0;
    //调用远程方法
    //注意第三个参数是指针类型
    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方式是数据编码采用了json,而不是gob编码。

服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main;
 
import (
    "net"
    "log"
    "net/rpc"
    "net/rpc/jsonrpc"
)
 
//注意字段必须是导出
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服务
    rpc.Register(rect);
    //获取tcpaddr
    tcpaddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080");
    chkError(err);
    //监听端口
    tcplisten, err2 := net.ListenTCP("tcp", tcpaddr);
    chkError(err2);
    for {
        conn, err3 := tcplisten.Accept();
        if err3 != nil {
            continue;
        }
        //使用goroutine单独处理rpc连接请求
        //这里使用jsonrpc进行处理
        go jsonrpc.ServeConn(conn);
    }
}

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main;
 
import (
    "fmt"
    "log"
    "net/rpc/jsonrpc"
)
 
type Params struct {
    Width, Height int;
}
 
func main() {
    //连接远程rpc服务
    //这里使用jsonrpc.Dial
    rpc, err := jsonrpc.Dial("tcp", "127.0.0.1:8080");
    if err != nil {
        log.Fatal(err);
    }
    ret := 0;
    //调用远程方法
    //注意第三个参数是指针类型
    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);
}

posted on   怀素真  阅读(5357)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示