代码之家  ›  专栏  ›  技术社区  ›  fluffy

在RPC调用中确定请求者的IP地址

  •  1
  • fluffy  · 技术社区  · 12 年前

    在Go中使用标准 net/rpc 功能,我想确定入站RPC请求来自哪个IP地址。基础 http 功能似乎在 http.Request 对象,但我看不到从默认RPC处理程序(使用 rpc.HandleHTTP )。

    是否有某种隐藏的机制可以触及底层 http请求 ,还是我必须做一些更花哨的事情来设置一个不同的HTTP响应程序?

    4 回复  |  直到 12 年前
        1
  •  4
  •   nemo    12 年前

    据我所知,不可能从默认服务器中的某个位置获取地址。

    这个 service call method ,调用请求接收功能,不提供对存储在编解码器中的远程数据的任何访问。

    如果http处理程序可以注册两次( which they can't ),您本可以覆盖 DefaultRPCPath 用于HTTP处理程序的设置 HandleHTTP 。但这很简单 not possible today

    您可以在不需要太多麻烦的情况下,使用自己的RPC服务器在默认服务器的基础上构建一个RPC服务器 ServeHTTP 方法:

    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 := &myRPCServer{rpc.NewServer()}
        srv.HandleHTTP(rpc.DefaultRPCPath, rpc.DefaultDebugPath)
    
        // ...http listen code...
    }
    

    当然,这样做的缺点是,你不能使用 rpc.Register 不再你必须写 srv.Register

    编辑: 我忘了你需要自己写 处理HTTP 也原因是,如果嵌入RPC服务器并编写 srv.HandleHTTP 它是在嵌入式实例上调用的,将嵌入式实例传递给 http.Handle() ,忽略您自己对 服务HTTP 。这有一个缺点,即您将无法使用调试路径调试RPC服务器,因为服务器的 处理HTTP 使用 private debug handler ( rpc.debugHTTP )无法访问。

        2
  •  1
  •   valyala    9 年前

    您也可以使用 https://github.com/valyala/gorpc 而不是net/rpc,后者将客户端地址传递给rpc服务器处理程序-请参阅 http://godoc.org/github.com/valyala/gorpc#HandlerFunc 详细信息。

        3
  •  1
  •   Jeremy Wall    12 年前

    这个 net/rpc 包的抽象级别高于tcp或http。由于它可以使用多个编解码器,因此提供获取入站rpc的ip地址的方法是没有意义的。理论上,有人可以实现一个在unix套接字上说话的代码,而不是使用无线电发射机。

    如果你想访问传输层的细节,你必须在堆栈中放下一个级别,然后使用 net net/http 目录来创建您的rpc服务。

        4
  •  0
  •   andy    8 年前

    目前似乎没有办法在rpc函数中做到这一点。 看看这个 link 了解更多信息

    这是一个总结。

    问:

    现在只能调用RemoteAddr()方法来获取上的RPC客户端地址 net.Conne,但假设您的服务器有多个 客户端已连接,并且每个客户端都在调用RPC导出的方法。有吗 一种实现从RPC内部获取调用方远程地址的方法的方法 方法

    func(t*Type)方法(args*args,reply*string)错误{
    //类似于
    *reply=调用方.RRemoteAddr().String()
    //现在谁调用了这个方法?
    返回0
    }

    A:

    我对此持怀疑态度。它需要API更改(不一定是向后不兼容的更改 但仍有一点重新设计)来提供这一点。