内容简介:在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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- php实现mysql连接池效果实现代码
- java并发实战:连接池实现
- Django+Vue实现WebSocket连接
- 实现WebRTC P2P连接
- Swoole MySQL 连接池的实现
- Swoole Redis 连接池的实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Flask Web开发:基于Python的Web应用开发实战
[美] Miguel Grinberg / 安道 / 人民邮电出版社 / 2014-12 / 59.00元
本书不仅适合初级Web开发人员学习阅读,更是Python程序员用来学习高级Web开发技术的优秀参考书。 • 学习Flask应用的基本结构,编写示例应用; • 使用必备的组件,包括模板、数据库、Web表单和电子邮件支持; • 使用包和模块构建可伸缩的大型应用; • 实现用户认证、角色和个人资料; • 在博客网站中重用模板、分页显示列表以及使用富文本; • 使用基于......一起来看看 《Flask Web开发:基于Python的Web应用开发实战》 这本书的介绍吧!