首先参考了 Erlang 官方文档和 http://blog.developers.api.sina.com.cn/?tag=erlang 以及 http://kazmier.net/computer/port-howto/ .
研读了将近24个小时, 才终于完全把问题解决. 开始 python 一直是broken pipe.后来才知道是管道中断导致的问题.
接着我排除了python的问题, 在erlang上面发现了Timeout, 感谢litaocheng的提醒,翻看了文档,把gen_server:call 的超时控制为infinity, 这样完全排除了超时的错误.
后来发现执行combin()之后,系统一直在等待. 我重新参考了下前面的2个成功案例,数据流的结尾应该
加上"\n"(windows为"\t\n"),并且erlang需要转换二进制,于是就是
String = list_to_binary("combine|"++_String++"\n"),
python端就成功收到了Stream.
这里combine只是我自己定的一个通信协议 合成请求|String1,String2 => string1+string2.
%%%-------------------------------------------------------------------
%%% File : gen_server_template.full
%%% Designer : free.Won <freefis@Gmail.com>
%%% Description :
%%% Communication between Python and Erlang via Stdio.
%%% Archieved : Mar 24 2009 by free.Wang <freefis@Gmail.com>
%%%-------------------------------------------------------------------
-module(comm).
-behaviour(gen_server).
%% API
-export([start/0,combine/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-record(state, {port}).
start() ->
gen_server:start_link({global, ?MODULE}, ?MODULE, [], []).
init([]) ->
process_flag(trap_exit, true),
Port = open_port({spawn, "python -u /home/freefis/Desktop/comm.py"},[stream,{line, 1024}]),
{ok, #state{port = Port}}.
handle_call({combine,String}, _From, #state{port = Port} = State) ->
port_command(Port,String),
receive
{Port,{data,{_Flag,Data}}} ->
io:format("receiving:~p~n",[Data]),
sleep(2000),
{reply, Data, Port}
end.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(Info, State) ->
{noreply,State}.
% {stop, {port_terminated, Reason}, Port}.
terminate(_Reason, Port) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
sleep(T) ->
receive
after T ->
true
end.
combine(_String) ->
String = list_to_binary("combine|"++_String++"\n"),
gen_server:call({global,?MODULE},{combine,String},infinity).
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#-------------------------------------------
# Designer : Free.Wang
# E-mail : freefis@Gmail.com
# Licence : License on GPL Licence
# Archieved : Dec 27 2008
#-------------------------------------------
import sys
def handle(_string):
if _string.startswith("combine|"):
string = "".join( _string[8:].split(","))
return string
"""waiting for input """
while 1:
# Recv. Binary Stream as Standard IN
_stream = sys.stdin.readline()
if not _stream: break
# Scheme, Turn into Formal String
inString = _stream.strip("\r\n")
# handle String
outString = handle(inString)
# send to port as Standart OUT
sys.stdout.write("%s\n" % (outString,))
sys.exit(0)
No comments:
Post a Comment