rpc.ServerCodec仍然在服务吗?

狼 :

我在进行一些RPC测试,偶然发现了一个似乎无法解决的问题。在测试中,我创建了三个单独的RPC服务器,我尝试关闭所有这些服务器并关闭它们。但是,在执行上一个测试(TestRpcCodecServerClientComm)后,​​即使我已尝试了所有可以确保确保执行的操作,但我的客户端连接似乎都已连接到我启动的第一个RPC服务器(我知道这一点是因为我有时将ID附加到RPCHandlers)。它被关闭了。尽管代码不存在,但我尝试检查所有可能的错误,但这并没有带来任何好处。

rpc.go

package rbot

import (
    "io"
    "net"
    "net/rpc"
    "net/rpc/jsonrpc"
)

func RpcCodecClientWithPort(port string) (rpc.ClientCodec, error) {
    conn, err := net.Dial("tcp", "localhost:"+port)
    if err != nil {
        return nil, err
    }
    return jsonrpc.NewClientCodec(conn), nil
}

func RpcCodecServer(conn io.ReadWriteCloser) rpc.ServerCodec {
    return jsonrpc.NewServerCodec(conn)
}

rpc_test.go

package rbot

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

type RPCHandler struct {
    RPCServer net.Listener
    conn      rpc.ServerCodec
    done      chan bool
    TestPort  string
    stop      bool
    GotRPC    bool
}

func (r *RPCHandler) SetupTest() {
    r.stop = false
    r.GotRPC = false
    r.done = make(chan bool)
    r.TestPort = "5556"
}

// TODO: Create separate function to handle erroring
func (r *RPCHandler) CreateRPCServer() error {
    rpc.RegisterName("TestMaster", TestAPI{r})

    var err error
    r.RPCServer, err = net.Listen("tcp", ":"+r.TestPort)

    if err != nil {
        return err
    }

    go func() {
        for {
            conn, err := r.RPCServer.Accept()
            if err != nil || r.stop {
                r.done <- true
                return
            }
            r.conn = RpcCodecServer(conn)
            rpc.ServeCodec(r.conn)
        }
    }()
    return nil
}

func (r *RPCHandler) CloseRPCServer() error {
    r.stop = true
    if r.conn != nil {
        err := r.conn.Close()
        if err != nil {
            fmt.Println(err)
        }
    }
    err := r.RPCServer.Close()
    <-r.done
    return err
}

type TestAPI struct {
    t *RPCHandler
}

func (tapi TestAPI) Send(msg string, result *string) error {
    if msg == "Got RPC?" {
        tapi.t.GotRPC = true
        return nil
    }
    return errors.New("Didn't receive right message")
}

// Check if we can create and close an RPC server successfully using the RPC server codec.
func TestRpcCodecServer(t *testing.T) {
    r := RPCHandler{}
    r.SetupTest()

    err := r.CreateRPCServer()
    if err != nil {
        t.Fatalf("Could not create rpc server! %s:", err.Error())
    }

    err = r.CloseRPCServer()
    if err != nil {
        t.Fatalf("Could not close RPC server! %s:", err.Error())
    }
}

// Check if we can create a client without erroring.
func TestRpcCodecClientWithPortt(t *testing.T) {
    r := RPCHandler{}
    r.SetupTest()
    r.CreateRPCServer()
    defer r.CloseRPCServer()

    RPCClient, err := RpcCodecClientWithPort(r.TestPort)
    defer RPCClient.Close()
    if err != nil {
        t.Fatalf("Could not create an RPC client! %s:", err.Error())
    }
}

// Let's double check and make sure our server and client can speak to each other
func TestRpcCodecServerClientComm(t *testing.T) {
    r := RPCHandler{}
    r.SetupTest()
    r.CreateRPCServer()
    defer r.CloseRPCServer()

    RPCCodec, _ := RpcCodecClientWithPort(r.TestPort)
    RPCClient := rpc.NewClientWithCodec(RPCCodec)
    defer RPCClient.Close()

    var result string
    err := RPCClient.Call("TestMaster.Send", "Got RPC?", &result)
    if err != nil {
        t.Fatalf("Error while trying to send RPC message: %s", err.Error())
    }

    if !r.GotRPC {
        t.Fatalf("Could not send correct message over RPC")
    }
}

不知道如果我只是处理不正确的连接或类似的东西,任何帮助将不胜感激。

记录 RPC API确实收到正确的字符串消息

吉姆:

尽管不是问题的根源,但是测试配置中有一些竞争条件,在这些条件引起问题之前应加以注意。始终检查-race选件是否存在问题您还应该让操作系统分配端口,以免发生冲突。例如,查看httptest.Server工作原理。

您在这里的失败是,您没有rpc.Server为每个测试创建新的测试,而是在重用rpc.DefaultServer第一次调用以名称CreateRPCServer注册a 每个后续调用使用已注册的实例。TestAPITestMaster

如果您rpc.Server每次设置测试都创建一个新测试并注册一个新的TestAPI,则最终测试将通过。

srv := rpc.NewServer()
srv.RegisterName("TestMaster", testAPI)

...
// and then use srv to handle the new connection
srv.ServeCodec(RpcCodecServer(conn))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章