0

如何向远程 Elixir GenServer 发送消息,然后使用C Erlang 接口接收调用结果?

我想在 C 中运行类似于

{result1, result2} = GenServer.call(MyModule.NodeName, {:dothing, "blah"})

这是我到目前为止所拥有的。它编译并连接到远程服务器并运行ei_reg_send而不会导致错误,但远程服务器没有收到响应。(我打开了一个记录器,所以我知道什么时候来电。)

#include <erl_interface.h>
#include <ei.h>

#define COOKIE "cookieval"
#define HOST "name@host"

int main() {
  ei_init();
  ei_cnode ec;
  int n = 0;
  int sockfd;
  int self;
  if((self = ei_connect_init(&ec, "nss", COOKIE, n++)) < 0) {
    return 1;
  }
  if((sockfd = ei_connect(&ec, HOST)) < 0) {
    return 2;
  }

  ei_x_buff request;
  ei_x_new(&request);
  ei_x_format(&request, "{dothing, ~a}", "blah");
  if(ei_reg_send(&ec, sockfd, "MyModule.NodeName", request.buff, request.index) < 0) {
    return 3;
  }
  ei_x_free(&request);
  // code makes it to here, but there's no indication that the genserver was called
  return 0;
}
4

2 回答 2

3

你不能GenServer.call/2在 C 节点中做。至少不是直接的,因为这不是公共 API,在这种情况下消息的外观如何(不是说它改变了很多,但你不能依赖它)。相反,您可以做的是发送常规消息并在handle_info.

于 2019-09-11T18:10:08.240 回答
0

正如所指出的,直接从 C 调用具有预定名称的 GenServer 比预期的要困难。我最终做的是在 Elixir 中创建一个模块函数,它调用 GenServer 本身并将结果返回给调用者。然后我使用 RPC 函数在 C 中与它交互。

  ei_x_buff request;                                                               
  ei_x_new(&request);                                                              
  ei_x_format_wo_ver(&request, "[~s]", "My Argument");                                      
  ei_x_buff response;                                                              
  ei_x_new(&response);                                                             
  ei_rpc(&ec, sockfd, "Elixir.MyModule", "dothing", request.buff, request.index, &response);

http://erlang.org/doc/man/ei_connect.html#ei_rpc

请注意,ei_rpc它不会在其响应缓冲区中返回“版本幻数”,但ei_rpc_from 返回.

于 2019-09-12T19:32:03.217 回答