Erlang 与 Java 创建的节点通讯

文章转自:https://blog.csdn.net/mycwq/article/details/38448813
我们知道,erlang在开源社区的活跃度远远不及java社区,在java社区中有很多优秀的开源框架,比如struts、hibernate、 spring、hadoop、hbase等,为了让erlang和java社区的众多开源框架相结合,让他们优势互补,可以让erlang来调用java写的中间件。

erlang提供了一个Jinterface代码包,java可以和erlang建立节点通信。通过这种方式,erlang可以将 java构建的节点也当作erlang的一个节点,java可以接收erlang传过来的消息,并且处理之后以异步的方式发送处理结果。

erlang与java构建的节点通讯
安装erlang后,可以在安装目录找到这个Jinterface代码包 OtpErlang.jar,路径是 erl5.10.3\lib\jinterface-1.5.8\priv\OtpErlang.jar
这里写图片描述

Java代码如下:

package erljava;

import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangPid;
import com.ericsson.otp.erlang.OtpErlangTuple;
import com.ericsson.otp.erlang.OtpMbox;
import com.ericsson.otp.erlang.OtpNode;

public class ErlJavaNode{

    public static void main(String[] args) throws Exception {

        String cookie = "123456";
        OtpNode node = new OtpNode("java_node@127.0.0.1", cookie);
        OtpMbox mbox = node.createMbox();
        mbox.registerName("java_node_name");

        System.out.println("java node start");

        OtpErlangObject o;
        OtpErlangTuple msg;
        OtpErlangPid from;

        while (true) {
            try {
                o = mbox.receive();
                System.out.println("recv:" + o);
                if (o instanceof OtpErlangTuple) {
                    msg = (OtpErlangTuple) o;
                    from = (OtpErlangPid) (msg.elementAt(0));
                    mbox.send(from, msg.elementAt(1)); // 原消息返回
                }
            } catch (Exception e) {
                System.out.println("" + e);
            }
        }
    }
}

erlang给Java节点发送消息:

C:\>erl -name erl_node@127.0.0.1 -setcookie 123456
Eshell V5.10.3  (abort with ^G)
(erl_node@127.0.0.1)1> {java_node_name,'java_node@127.0.0.1'} ! {self(),{a,bc,d}}.
{<0.37.0>,{a,bc,d}}
(erl_node@127.0.0.1)2> flush().
Shell got {a,bc,d}
ok

分析erlang与Java节点无法通讯
1、epmd服务未启动

先在本机启动一个erlang节点,没有的话,如果先执行Java代码系统会抛出异常。原因是所有erlang节点之间的通讯都要依赖一个底层的epmd的服务,这个模块的主要功能是提供通过相互通过name来识别机器的机制。这个机制类似dns功能,先通过一个名称服务中间件,使用name获取所对应的ip地址,然后再利用这个ip地址建立连接。

另一种方式是手动启动epmd服务,在erlang安装目录下找到epmd进程,执行命令 epmd -daemon

2、erlang版本不一致

java使用的OtpErlang包和shell使用的erlang版本不一致,erlang是不允许主版本不同的erlang节点进行连接。

3、cookie
cookie 必须一致

erlang与java节点通讯的好处
erlang节点通讯也是依靠socket实现的,虽然erlang和java可以直接用socket连接,但使用节点通讯的有很多好处,和erlang节点通讯一样,支持erlang所有的数据结构,而且还不用定义传输协议,多节点通讯也会变得复杂。做成erlang节点,能极大程度利用到erlang分布式的好处。

Java判断erlang节点是否连接成功

if (node.ping("erl_node@127.0.0.1", 2000)) {
    System.out.println("connect ok");
} else {
    System.out.println("connect fail");
}

Java主动与erlang节点通讯实例
前面说到是erlang连接java节点的情况,现在讨论java主动连接erlang节点的情况。
erlang建立节点,注册进程名字

C:\>erl -name erl_node@127.0.0.1 -setcookie 123456
Eshell V5.10.3  (abort with ^G)
(erl_node@127.0.0.1)1> register(erl_node_name, self()).
true

Java代码如下

package erljava;

import com.ericsson.otp.erlang.OtpConnection;
import com.ericsson.otp.erlang.OtpErlangAtom;
import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangTuple;
import com.ericsson.otp.erlang.OtpPeer;
import com.ericsson.otp.erlang.OtpSelf;

public class ErlJavaNode {

    public static void main(String[] args) throws Exception {

        String cookie = "123456";

        OtpSelf self = new OtpSelf("java_node@127.0.0.1", cookie);
        OtpPeer other = new OtpPeer("erl_node@127.0.0.1");
        OtpConnection connection = self.connect(other);
        System.out.println("java node start");

        if (connection.isConnected()) {
            System.out.println("connect ok");

            OtpErlangObject[] msg = new OtpErlangObject[2];
            msg[0] = self.pid();
            msg[1] = new OtpErlangAtom("hello, world");
            OtpErlangTuple tuple = new OtpErlangTuple(msg);
            connection.send("erl_node_name", tuple);
        } else {
            System.out.println("connect fail");
        }
    }
}

erlang刷新信箱,就可以看到Java发来的信息

(erl_node@127.0.0.1)2> flush().
Shell got {<6872.1.0>,'hello, world'}
ok
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值