在 RPC 调用中确定请求者的 IP 地址
Posted
技术标签:
【中文标题】在 RPC 调用中确定请求者的 IP 地址【英文标题】:Determining requester's IP address in RPC call 【发布时间】:2012-09-27 21:14:42 【问题描述】:在使用标准 net/rpc
功能的 Go 中,我想确定入站 RPC 请求来自哪个 IP 地址。底层的http
功能似乎在http.Request
对象中提供了此功能,但我看不到任何从默认RPC 处理程序(使用rpc.HandleHTTP
设置)中获取此功能的方法。
是否有一些隐藏的机制可以获取底层 http.Request
,或者我是否必须做一些更有趣的事情来设置不同的 HTTP 响应器?
【问题讨论】:
为什么要ip地址? @JeremyWall 我需要它来进行日志记录/调试,如果也能对某些东西进行简单的完整性检查,那就太好了。 【参考方案1】:据我所知,无法从默认服务器的某处获取地址。
调用请求接收函数的service call method不提供对存储在编解码器中的远程数据的任何访问。
如果可以注册两次 http 处理程序 (which they can't),则您可以覆盖 DefaultRPCPath
用于由HandleHTTP
设置的 HTTP 处理程序。但这只是not possible today。
你可以做的,不用大惊小怪,就是在默认服务器的基础上用你自己的ServeHTTP
方法构建一个RPC服务器:
import (
"log"
"net"
"net/http"
"net/rpc"
)
type myRPCServer struct
*rpc.Server
func (r *myRPCServer) ServeHTTP(w http.ResponseWriter, req *http.Request)
log.Println(req.RemoteAddr)
r.Server.ServeHTTP(w, req)
func (r *myRPCServer) HandleHTTP(rpcPath, debugPath string)
http.Handle(rpcPath, r)
func main()
srv := &myRPCServerrpc.NewServer()
srv.HandleHTTP(rpc.DefaultRPCPath, rpc.DefaultDebugPath)
// ...http listen code...
当然,这样做的缺点是您不能再使用rpc.Register
。你必须写srv.Register
。
编辑:我忘了你还需要写自己的HandleHTTP
。这样做的原因是,如果您嵌入 RPC 服务器并编写 srv.HandleHTTP
,它会在嵌入实例上调用,将嵌入实例传递给 http.Handle()
,而忽略您自己对 ServeHTTP
的定义。这有一个缺点,您将无法使用调试路径调试 RPC 服务器,因为服务器的 HandleHTTP
使用您无法访问的 private debug handler (rpc.debugHTTP
)。
【讨论】:
这看起来是一个不错的方法,而且我认为这是必要的。不过,我完全是 Go 新手,所以我可能需要一段时间才能将这些部分组合在一起。【参考方案2】:您也可以使用https://github.com/valyala/gorpc 代替 net/rpc,它将客户端地址传递给 RPC 服务器处理程序 - 有关详细信息,请参阅 http://godoc.org/github.com/valyala/gorpc#HandlerFunc。
【讨论】:
谢谢!大约三年前我从事的项目对我来说早已不复存在,但希望这对将来有同样问题的人有用。【参考方案3】:net/rpc
包的抽象级别比 tcp 或 http 更高。由于它可以使用多个编解码器,因此提供一种获取入站 rpc 的 IP 地址的方法是没有意义的。从理论上讲,有人可以实现一个在 unix 套接字上进行通信的代码,或者使用无线电发射器。
如果您想访问传输层的细节,您必须在堆栈中删除一个级别并使用net
或net/http
目录来创建您的 rpc 服务。
【讨论】:
我认为它处于更高的抽象级别,但没有理由不能有一个接口来获取底层传输机制。现在的 API 似乎没有为此提供任何未来的钩子,尽管处理程序的存根类型名的接口可能会在未来成为那个。【参考方案4】:目前似乎没有办法在 rpc 函数中执行此操作。 请参阅此link 了解更多信息
这是一个摘要。
问:
现在只能调用 RemoteAddr() 方法来获取 RPC 客户端的地址 net.Conn 当客户端拨号到服务器时,但假设您的服务器有多个 连接的客户端,并且每个客户端都在调用 RPC 导出方法。有没有 一种实现从 RPC 内部获取调用者远程地址的方法的方法 方法?
func (t *Type) Method(args *Args, reply *string) 错误 //类似 *reply = Caller.RemoteAddr().String() // 现在是谁调用了这个方法? 返回零
答:
我很怀疑。这将需要 API 更改(不一定是向后不兼容的 但仍然需要重新设计)来提供这个。
【讨论】:
以上是关于在 RPC 调用中确定请求者的 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章