简体   繁体   English

从C向GenServer发送消息

[英]Send message to GenServer from C

How do I send a message to a remote Elixir GenServer and then receive the results of the call using the C Erlang Interface ? 如何将消息发送到远程Elixir GenServer,然后使用C Erlang接口接收呼叫结果?

I want to run something in C analogous to 我想在C中运行类似于

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

Here's what I have so far. 到目前为止,这就是我所拥有的。 It compiles and connects to the remote server and runs ei_reg_send without causing an error, but the remote server doesn't receive a response. 它编译并连接到远程服务器,并运行ei_reg_send而不引起错误,但是远程服务器未收到响应。 (I have a logger turned on so I know when the call comes through.) (我打开了一个记录器,所以我知道电话何时接通。)

#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;
}

You cannot do GenServer.call/2 in C Node. 您不能在C节点中执行GenServer.call/2 At least not directly, due to fact that this is not public API how the messages in that case look like (not that it changes a lot, but you cannot rely on that). 至少不是直接的,因为这不是公共API,在这种情况下,消息的外观是这样的(不是变化很大,但是您不能依靠它)。 Instead what you can do is that you send regular message and handle that within handle_info . 相反,您可以做的是发送常规消息并在handle_info处理该消息。

Calling a GenServer with a predetermined name directly from C was, as pointed out, more difficult than expected. 如所指出的,直接从C调用具有预定名称的GenServer比预期的要困难得多。 What I ended up doing was creating a module function in Elixir that called the GenServer itself and returned the results to the caller. 我最后要做的是在Elixir中创建一个模块函数,该函数调用GenServer本身并将结果返回给调用方。 Then I interfaced with this in C using RPC functions. 然后,我使用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);

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

Note that ei_rpc doesn't return a "version magic number" in its response buffer but ei_rpc_from does . 请注意, ei_rpc在其响应缓冲区中不返回“版本魔数”,但ei_rpc_from 会返回

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM