【问题标题】:Keeping connection for Golang net/rpc保持 Golang net/rpc 的连接
【发布时间】:2022-01-16 12:23:46
【问题描述】:

据我了解,请在此处阅读 net/rpc 包文档 https://pkg.go.dev/net/rpc@go1.17.5 每次客户端对服务器进行 rpc 调用时,都会建立一个新连接。如何实现每个新客户端打开一个新连接、使其保持活动状态并仅使用 TPC(即不使用 HTTP)调用 RPC 方法?

【问题讨论】:

  • 为什么你认为每次调用都会调用一个新的连接?
  • @JimB 阅读文档后。我还没有看到任何关于保持连接等的内容。
  • “一个希望使用该服务的客户端建立一个连接,然后在连接上调用NewClient,一个客户端基于单个连接
  • 是的,远程调用后会发生什么?我猜,连接自动关闭。我需要有可能保留服务器上所有打开连接的列表
  • 连接由client 保留,直到应用程序明确closes the client。应用程序必须关闭客户端以防止泄漏。无需将所有打开的客户端列表保存到服务器 - 只需将单个客户端重用到服务器即可。

标签: go rpc


【解决方案1】:

如果您使用任何标准库方法创建新客户端:

client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
if err != nil {
    log.Fatal("dialing:", err)
}

在底层它将call net.Dial,产生一个与rpc.Client关联的连接:

conn, err := net.Dial(network, address)

您可以看到 NewClient 在此处实例化时采用单个连接:https://cs.opensource.google/go/go/+/refs/tags/go1.17.5:src/net/rpc/client.go;l=193-197;drc=refs%2Ftags%2Fgo1.17.5;bpv=1;bpt=1

在该客户端上对Client.Call 的任何调用都将写入和读取该底层连接,而不会产生新连接。

因此,只要您一次实例化您的客户端,然后对同一客户端进行所有 rpc 调用,您将始终使用单个连接。如果该连接被切断,客户端将不再可用。

rpc.Client 也是线程安全的,因此您可以安全地创建它并在所有地方使用它,而无需建立新的连接。


回答您的评论。如果您想运行 rpc 服务器并跟踪连接,您可以这样做:

l, e := net.Listen("tcp", ":1234")
if e != nil {
    log.Fatal("listen error:", e)
}
server := rpc.NewServer()
for {
    conn, err := l.Accept()
    if err != nil {
        panic(err) // replace with log message?
    }
    // Do something with `conn`
    go func() {
        server.ServeConn(conn)
        // The server has stopped serving this connection, you can remove it.
    }()
}

然后在每个连接进入时对其进行处理,并在完成处理后将其删除。

【讨论】:

  • 谢谢,保存所有连接列表并在需要时(通过服务器)访问它们的服务器代码是什么?我看到了这段代码,这是否意味着 rpc.ServeConn 调用在内部保持此连接处于活动状态? ..如果我想访问所有连接,我需要在调用之前保存一个指向 conn 的链接吗?对于 { conn, err := listener.Accept() if err != nil { continue } rpc.ServeConn(conn) } 这里ipfs.io/ipfs/QmfYeDhGH9bZzihBUDEQbCbTc5k5FZKURMUoUvfmc27BwL/rpc/…
  • 编辑:哦,我明白你在说什么,让我在答案中添加如何做到这一点
  • 以上已回答 ^
猜你喜欢
  • 1970-01-01
  • 2020-12-19
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
  • 2017-07-27
  • 2011-03-14
  • 1970-01-01
  • 2021-08-19
相关资源
最近更新 更多