前面的rpc调用虽然简单,但是和普通的http的调用差异不大,这次我们解决下面的问题:

1. serviceName统一和名称冲突的问题

  1. server端和client端如何统一serviceName
  2. 多个server的包中serviceName同名的问题

新建handler/handler.go文件内容如下: 为什么要新建一个文件? - 解耦

  1. package handler
  2. const HelloServiceName = "handler/HelloService"

1. 服务端

  1. package main
  2. import (
  3. "net"
  4. "net/rpc"
  5. "start/rpc_ch01/handler"
  6. )
  7. type HelloService struct {}
  8. func (s *HelloService) Hello(request string, reply *string) error {
  9. *reply = "hello "+ request
  10. return nil
  11. }
  12. func main(){
  13. _ = rpc.RegisterName(handler.HelloServiceName, &HelloService{})
  14. listener, err := net.Listen("tcp", ":1234")
  15. if err != nil {
  16. panic("监听端口失败")
  17. }
  18. conn, err := listener.Accept()
  19. if err != nil {
  20. panic("建立链接失败")
  21. }
  22. rpc.ServeConn(conn)
  23. }

2. 客户端

  1. package main
  2. import (
  3. "fmt"
  4. "net/rpc"
  5. "start/rpc_ch01/handler"
  6. )
  7. func main() {
  8. client, err := rpc.Dial("tcp", "localhost:1234")
  9. if err != nil {
  10. panic("连接到服务器失败")
  11. }
  12. var reply string
  13. err = client.Call(handler.HelloServiceName+".Hello", "imooc", &reply)
  14. if err != nil {
  15. panic("服务调用失败")
  16. }
  17. fmt.Println(reply)
  18. }

2. 继续屏蔽HelloServiceName和Hello函数名称

1. handler源码

  1. package handler
  2. type HelloService struct{}
  3. func (s *HelloService) Hello(request string, reply *string) error {
  4. *reply = "hello " + request
  5. return nil
  6. }

2. 服务端代理

  1. package server_proxy
  2. import "net/rpc"
  3. const HelloServiceName = "handler/HelloService"
  4. type HelloServiceInterface interface {
  5. Hello(request string, reply *string) error
  6. }
  7. func RegisterHelloService(srv HelloServiceInterface) error {
  8. return rpc.RegisterName(HelloServiceName, srv)
  9. }

3. 服务端

  1. package main
  2. import (
  3. "net"
  4. "net/rpc"
  5. "start/rpc_ch01/handler"
  6. "start/rpc_ch01/server_proxy"
  7. )
  8. func main(){
  9. hellohandler := &handler.HelloService{}
  10. _ = server_proxy.RegisterHelloService(hellohandler)
  11. listener, err := net.Listen("tcp", ":1234")
  12. if err != nil {
  13. panic("监听端口失败")
  14. }
  15. conn, err := listener.Accept()
  16. if err != nil {
  17. panic("建立链接失败")
  18. }
  19. rpc.ServeConn(conn)
  20. }

4. 客户端代理

  1. package client_proxy
  2. import "net/rpc"
  3. const HelloServiceName = "handler/HelloService"
  4. type HelloServiceClient struct{
  5. *rpc.Client
  6. }
  7. func NewClient(address string) HelloServiceClient {
  8. conn, err := rpc.Dial("tcp", address)
  9. if err != nil {
  10. panic("连接服务器错误")
  11. }
  12. return HelloServiceClient{conn}
  13. }
  14. func (c *HelloServiceClient) Hello(request string, reply *string) error {
  15. err := c.Call(HelloServiceName+".Hello", request, reply)
  16. if err != nil {
  17. return err
  18. }
  19. return nil
  20. }

5. 客户端

  1. package main
  2. import (
  3. "fmt"
  4. "start/rpc_ch01/client_proxy"
  5. )
  6. func main(){
  7. client := client_proxy.NewClient("localhost:1234")
  8. var reply string
  9. err := client.Hello("bobby",&reply)
  10. if err != nil {
  11. panic("调用失败")
  12. }
  13. fmt.Println(reply)
  14. }