2015-04-07 78 views
2

目前我的Erlang应用程序在escript(TCP服务器)中启动,并且所有工作都正常,因为它使用我提供的默认端口。现在我想通过escript将端口传递给应用程序,但我不知道如何。 (该应用程序运行主管Erlang escript使用启动参数启动应用程序

script.escript

!/usr/bin/env escript 
%% -*- erlang -*- 

-export([main/1]). 

main([UDPort, TCPort]) -> 
    U = list_to_integer(UDPort), 
    T = list_to_integer(TCPort), 

    app:start(), %% Want to pass T into the startup. 
    receive 
    _ -> ok 
    end; 

... 

app.erl

-module(app). 
-behaviour(application). 

-export([start/0, start/2, stop/0, stop/1]). 

-define(PORT, 4300). 

start() -> application:start(?MODULE). %% This is called by the escript. 
stop() -> application:stop(?MODULE). 

start (_StartType, _StartArgs) -> supervisor:start(?PORT). 
stop (_State) -> ok. 

我真的不知道这是可能的使用应用程序,但我认为最好只是问。

回答

2

的常用方法是开始从任何外壳事情就打电话

erl -run foo 

但你也可以做

erl -appname key value 

设置环境值,然后

application:get_env(appname, key) 

以获得您正在寻找的价值。

也就是说......

我喜欢有服务应用程序是事情,不必关机是配置(重新)。我通常会包含一些消息协议,如{config, Aspect, Setting}或类似的可以即时更改服务基本状态的消息协议。因为我经常这样做,所以我通常只是在启动应用程序的任何脚本后才发送一个配置消息给它。

所以考虑到这一点,认为这是粗略的概念例如:

!/usr/bin/env escript 
%% -*- erlang -*- 

-export([main/1]). 

main([UDPort, TCPort]) -> 
    U = list_to_integer(UDPort), 
    T = list_to_integer(TCPort), 
    ok = case whereis(app) of 
     undefined -> app:start(); 
     _Pid  -> ok 
    end, 
    ok = set_ports(U, T). 

%% Just an illustration. 
%% Making this a synchronous gen_server/gen_fsm call is way better. 
set_ports(U, T) -> 
    app ! {config, listen, {tcp, T}}, 
    app ! {config, listen, {udp, U}}, 
    ok. 

现在不仅是启动脚本启动脚本,它也是一个配置脚本。重点不在于拥有启动脚本,而是在指定的端口上运行服务。当然,这不是对所有工具的概念适合,但它应该给你一些想法。还有一种将配置文件放在应用程序知道要查看的地方,只读其中的术语以及其他技术(如包括应用程序规范中的端口等)的做法。

编辑

我才意识到你是在escript将每次调用时产生一个新的节点做这个。要使上述技巧正常工作,您需要将escript名称作为运行服务的节点,并在已存在的情况下找到该节点。