是否可以发送函数作为 RPC 的响应

Posted

技术标签:

【中文标题】是否可以发送函数作为 RPC 的响应【英文标题】:Is it possible to send a function as response of RPC 【发布时间】:2021-02-21 09:37:49 【问题描述】:

我正在尝试实现一个服务器和多个客户端。 客户端将向服务器注册,服务器应该给客户端一个特定的函数来调用。 我不希望特定函数成为另一个 rpc 调用。我正在尝试为 map reduce 构建一个分布式系统,该系统将在客户端进程中执行该函数。

有没有办法将函数作为响应传递给 Go 中的远程过程调用? 以下是我尝试过的:

在服务器中:

type ResgisterResponse struct 
    Ack     bool
    MapFunc func()


func (a *API) RegisterWorker(addr string, reply *ResgisterResponse) error 
    a.worker[addr] = "idle" //idle, working, complete
    fmt.Printf("Wokers : %+v\n", a.worker)
    *reply = ResgisterResponse
        Ack: true,
        MapFunc: func() 
            fmt.Println("Hello Worker")
        ,
    
    return nil

在客户端:

var reply struct 
        Ack     bool
        MapFunc func()
    
err = client.Call("API.RegisterWorker", getLocalAddr()+":"+localPort, &reply)
must(err)
fmt.Println("Worker registered")
reply.MapFunc()

这门课程我得到零指针错误。

panic: runtime error: invalid memory address or nil pointer dereference

【问题讨论】:

rpc的意义不就是调用客户端中的函数吗? 是的,但在这种情况下,我正在尝试实现一个 mapreduce 网络。所以我希望工人做这项工作。服务器将充当主人,只是告诉工人该做什么。 【参考方案1】:

由于语言设计,无法通过网络发送普通函数。在单个程序中,您可以将函数作为参数传递,因为它们是在同一个二进制文件中编译的。在服务器进程中,您可以获取它们的地址/引用,因为它们被映射到内存中,但是当您发送函数时,您实际上将指针发送给它,这不是客户端内存中的有效地址(因此出现无效指针错误)。

为了解决您的问题,我将让客户端根据 id(可能是提及函数名称的字符串)向服务器注册一组可用函数。服务端会在 Run RPC 调用中发回函数 id,客户端会根据这个 id 选择函数并运行它

还有一些实验库可以在运行时评估 Go 代码,但我认为它们不安全。 This 就是一个例子。

【讨论】:

感谢您的解释。我会让服务器发回函数 ID。但也许不是事先向服务器注册函数,而是使用 Golang 中的插件来加载与 id 匹配的函数。我认为这解决了它。

以上是关于是否可以发送函数作为 RPC 的响应的主要内容,如果未能解决你的问题,请参考以下文章

RabbitMQ 远程过程调用(RPC)

是否有任何浏览器支持以分块编码响应发送的预告片?

我可以发回函数引用作为对 api 请求的响应吗?

xpages JSON-RPC 服务处理来自回调函数的响应

将大型响应 Json 作为多部分数据或多个部分发送

在 JSON RPC 请求和响应之间实现通知