内容简介:在Erlang中,有很多种方式去实现与其他语言的交互,常见的几种方式有后面几种难度都是有的,也使用了比较复杂的C/C++,而且比较容易出现问题。TCP的方式是通过网络协议,个人也不是很喜欢,那就剩下Port方式去连接Erlang服务器。
title: 实现Golang和Erlang的连接(Port) categories: Golang
在Erlang中,有很多种方式去实现与其他语言的交互,常见的几种方式有
- 使用TCP协议交互
- 使用Port
- 使用Erl_Interface方式去实现
- CNode
- NIF
后面几种难度都是有的,也使用了比较复杂的C/C++,而且比较容易出现问题。TCP的方式是通过网络协议,个人也不是很喜欢,那就剩下Port方式去连接Erlang服务器。
在Erlang中使用Port非常简单,实际上就是通过标准输入输出流与外部程序就行交互。
现在我还是沿用官方文档中代码,仅做部分修改,实现Erlang与Golang的交互。
%% complex1.erl
-module(complex1).
-export([start/1, stop/0, init/1]).
-export([foo/1, bar/1]).
start(ExtPrg) ->
spawn(?MODULE, init, [ExtPrg]).
stop() ->
complex ! stop.
foo(X) ->
call_port({foo, X}).
bar(Y) ->
call_port({bar, Y}).
call_port(Msg) ->
complex ! {call, self(), Msg},
receive
{complex, Result} ->
Result
end.
init(ExtPrg) ->
register(complex, self()),
process_flag(trap_exit, true),
%% 注意{packet, 2}代表的是用2个字节表示传输的
%% Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
%% 在这里不去处理这个数据头,不需要这个参数
Port = open_port({spawn, ExtPrg}, []),
loop(Port).
loop(Port) ->
receive
{call, Caller, Msg} ->
Port ! {self(), {command, encode(Msg)}},
receive
{Port, {data, Data}} ->
Caller ! {complex, decode(Data)}
end,
loop(Port);
stop ->
Port ! {self(), close},
receive
{Port, closed} ->
exit(normal)
end;
{'EXIT', Port, Reason} ->
exit(port_terminated)
end.
%% 进行编码,将数据转成2进制
encode({foo, X}) -> <<1:8, X:8>>;
encode({bar, Y}) -> <<2:8, Y:8>>].
%% 这里有点特别,
decode(Data) -> erlang:list_to_binary(Data).
对于Golang,需要读取标准输入流的数据,这里我用bufio处理下(其实也没有太多必要,哈哈哈)。因为这里没有使用数据流的头部来记录数据的长度,所以默认将数据长度设置为2的byte数组。
// port.go
package main
import (
"bufio"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
for {
buff := make([]byte, 2)
_, err := reader.Read(buff)
if err != nil {
panic(err.Error())
}
switch int(buff[0]) {
case 1:
buff[1] = byte(foo(int(buff[1])))
case 2:
buff[1] = byte(bar(int(buff[1])))
}
writer.Write(buff[1:2])
// 这里需要注意,要用Flush进行处理,否则erlang端收不到信息
writer.Flush()
}
}
func foo(num int) int {
return num + 1
}
func bar(num int) int {
return 2 * num
}
使用
步骤1 编译port.go
go build port.go
步骤2 运行Erlang虚拟机
unix> erl
Erlang (BEAM) emulator version 4.9.1.2
Eshell V4.9.1.2 (abort with ^G)
1> c(complex1).
{ok,complex1}
步骤3 运行
2> complex1:start("extprg").
<0.34.0>
3> complex1:foo(3).
4
4> complex1:bar(5).
10
5> complex1:stop().
stop
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
零售的哲学:7-Eleven便利店创始人自述
[日] 铃木敏文 / 顾晓琳 / 江苏文艺出版社 / 2014-12-1 / 36
全球最大的便利店连锁公司创始人——铃木敏文,结合40多年零售经验,为你讲述击中消费心理的零售哲学。铃木敏文的很多创新,现在已经成为商界常识,本书把那些不可思议的零售创新娓娓道来。关于零售的一切:选址、订货、销售、物流、管理……他一次又一次地在一片反对声中创造出零售界的新纪录。 翻开本书,看铃木敏文如何领导7-11冲破层层阻碍,成为世界第一的零售哲学。一起来看看 《零售的哲学:7-Eleven便利店创始人自述》 这本书的介绍吧!
RGB HSV 转换
RGB HSV 互转工具
RGB CMYK 转换工具
RGB CMYK 互转工具