Из Erlang/Elixir в Java и обратно. Приключение на 20 минут

от автора

Всем хай!

Когда приходится общаться из Erlang/Elixir мира с Java и обратно — не так уж и много вариантов имеется. Всеми заброшенный jinterface и новая библиотека encon, базовый пример использования которой представлен под катом.

Добавление зависимостей

Добавляем Encon зависимость к JVM приложению:

Maven:

<dependencies>   ...   <dependency>     <groupId>io.appulse.encon</groupId>     <artifactId>encon</artifactId>     <version>1.6.4</version>   </dependency>   ... </dependencies>

Gradle:

dependencies {   compile 'io.appulse.encon:encon:1.6.4' }

ЗАМЕТЬТЕ: если есть такая необходимость (например проект на Ant), то зависимости в виде jar-файлов можно найти на GitHub, в разделе релизы.

Запуск Erlang-ноды

import io.appulse.encon.Node; import io.appulse.encon.Nodes; import io.appulse.encon.config.NodeConfig;  // Создание конфига ноды. // Больше деталей - см. проект encon-config NodeConfig config = NodeConfig.builder()     // true - для локальных нод,     // false (по умолчанию) - доступных извне     .shortName(true)     .cookie("secret")     .build();  // Созадние, регистрация в EPMD и запуск сервера новой Erlang ноды Node node = Nodes.singleNode("echo-node", config);

ЗАМЕТЬТЕ: что бы пример выше заработал, необходимо либо запустить демон EPMD или его Java-имплементацию.

Создание мейлбокса

Мейлбокс, он же процесс, в терминалогии Erlang:

import io.appulse.encon.mailbox.Mailbox;  Mailbox mailbox = node.mailbox()     .name("popa") // опционально     .build();

Подклчение к нодам

ЗАМЕТЬТЕ: Вы можете инициировать соединение из Erlang/Elixir или Java автоматически отправив сообщение, используя формат тюпла {Имя, Нода} или по PID’у (если он есть).

Можно начать общение между нодами с отправки ping-сообщения cо стороны Erlang через net_adm:ping/1:

(erlang@localhost)1> net_adm:ping('java@localhost'). pong (erlang@localhost)2>

Также возможно отправить сообщение на {Name, Node}, где Node это атом вида 'java@localhost', и Name это PID или зарегестрированное имя мейлбокса, который существует на стороне Java.

(erlang@localhost)1> {my_process, 'java@localhost'} ! hello. hello (erlang@localhost)2>

Если мейлбокс существует на стороне Java, то он получит сообщение.

Отправляем сообщение из Java

Есть целое семейство send-методов у Mailbox, которые доставляют:

  • send(ErlangPid, ErlangTerm) — отправляет сообщение на удалённый или локальный PID;
  • send(String, ErlangTerm) — пересылает терм на локальный мейлбокс по его имени этой же ноды;
  • send(String, String, ErlangTerm) — отправляет сообщение на удалённую/локальную ноду и мейлбокс по его имени.

Давайте попробуем, откроем Erlang-shell и зарегаем его с именем…'shell':

(erlang@localhost)1> erlang:register(shell, self()). true (erlang@localhost)2>

Теперь, мы можем отправить сообщулю из Java (связь с нодой будет установлена автоматически):

import static io.appulse.encon.terms.Erlang.atom;  mailbox.send("erlang@localhost", "shell", atom("hello"));

Возвращаемся в Erlang и читаем полученное сообщение:

(erlang@localhost) 1> flush(). Shell got hello ok (erlang@localhost) 2>

Получение сообщений в Java

Для получения входящего сообщения необходимо воспользоваться одним из Mailbox-методов: receive() или receive(timeout, timeUnit), которые могут бесконечно ждать нового сообщения или фиксированное количество времени.

import io.appulse.encon.Node; import io.appulse.encon.Nodes; import io.appulse.encon.config.NodeConfig; import io.appulse.encon.connection.regular.Message; import io.appulse.encon.mailbox.Mailbox;  public class Main {    public static void main (String[] args) {     NodeConfig config = NodeConfig.builder()         .shortName(true)         .build();      Node node = Nodes.singleNode("java@localhost", config);      Mailbox mailbox = node.mailbox()         .name("my_process")         .build();      Message message = mailbox.receive();     System.out.println("Incoming message: " + message.getBody().asText());   } }

Стартанём Erlang ноду и отправим сообщение:

$> erl -sname erlang@localhost ... (erlang@localhost)1> {my_process, 'java@localhost'} ! hello.

Заключение

Эти и многие другие примеры можно изучить на сайте проекта и/или на GitHub страничке.


ссылка на оригинал статьи https://habr.com/post/423719/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *