基于上下文我们可以针对不同客户端提供定制化的RPC服务。
我们可以通过为每个链接提供独立的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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
package main import ( "fmt" "log" "net" "net/rpc" ) const HelloConnServiceName = "HelloConnService" type HelloConnServiceInterface = interface { Hello(request string, reply *string) error Login(request string, reply *string) error } func RegisterHelloConnService(service HelloConnServiceInterface) error { return rpc.RegisterName(HelloConnServiceName, service) } type HelloConnService struct { conn net.Conn isLogin bool } func (p *HelloConnService) Hello(request string, reply *string) error { if !p.isLogin { return fmt.Errorf("please login") } *reply = "HelloConnService: " + request + ", from ip:" + p.conn.RemoteAddr().String() return nil } func (p *HelloConnService) Login(request string, reply *string) error { if request != "user:password" { return fmt.Errorf("auth failed") } log.Println("ip:" + p.conn.RemoteAddr().String() + " logined.") p.isLogin = true return nil } func main() { listener, err := net.Listen("tcp", ":1234") if err != nil { log.Fatal("ListenTCP error: ", err) } for { conn, err := listener.Accept() if err != nil { log.Fatal("Accept error", err) } go func() { defer conn.Close() p := rpc.NewServer() p.Register(&HelloConnService{conn: conn}) p.ServeConn(conn) log.Println("ip:" + conn.RemoteAddr().String() + " login out.") }() } } |
然后客户端代码如下:
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 ( "fmt" "log" "net/rpc" ) const HelloConnServiceName = "HelloConnService" type HelloConnServiceClient struct { *rpc.Client } func DialHelloConnService(network, address string) (*HelloConnServiceClient, error) { c, err := rpc.Dial(network, address) if err != nil { return nil, err } return &HelloConnServiceClient{Client: c}, nil } func (p *HelloConnServiceClient) Hello(request string, reply *string) error { return p.Client.Call(HelloConnServiceName+".Hello", request, reply) } func (p *HelloConnServiceClient) Login(request string, reply *string) error { return p.Client.Call(HelloConnServiceName+".Login", request, reply) } func main() { //虚拟机服务器ip是192.168.1.101, 本机IP地址是102 client, err := DialHelloConnService("tcp", "192.168.1.101:1234") if err != nil { log.Fatal("dialing: ", err) } var reply string err = client.Login("user:password", &reply) if err != nil { log.Fatal(HelloConnServiceName+".Hello error: ", err) } else { fmt.Println(reply) } err = client.Hello("NewClient, ip:192.168.1.102", &reply) if err != nil { log.Fatal(HelloConnServiceName+".Hello error: ", err) } else { fmt.Println(reply) } } |
这个就没啥好讲的,在单次服务里面加入了验证。
【Go】上下文信息