我花了几个小时尝试使用雅司文档和网络搜索来解决此问题。现有的帖子对我没有帮助。
我是erlang的新手,我正在尝试使用http://yaws.hyber.org/embed.yaws上提供的示例代码在嵌入模式下运行雅司病毒。我错过了一些东西,因为我无法让它工作。我有四个文件:
ybed.app
{application, ybed_app,
[
{description, "Yaws Embedded Application Test"},
{vsn, "0.1.0"},
{registered, []},
{applications, [kernel, stdlib, yaws]},
{mod, {ybed_app, []}},
{env, []}
]}.
ybed_app.erl
-module(ybed_app).
-behaviour(application).
%% Application callbacks
-export([start/2,
stop/1]).
start(_StartType, _StartArgs) ->
case ybed_sup:start_link() of
{ok, Pid} ->
{ok, Pid};
Other ->
{error, Other}
end.
stop(_State) ->
ok.
ybed_sup.erl
-module(ybed_sup).
-behaviour(supervisor).
%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
YBed = {ybed, {ybed,start,[]},
permanent,2000,worker,[ybed]},
{ok,{{one_for_all,0,1}, [YBed]}}.
ybed.erl
-module(ybed).
-compile(export_all).
start() ->
{ok, spawn(?MODULE, run, [])}.
run() ->
Id = "embedded",
GconfList = [{id, Id}],
Docroot = "/tmp",
SconfList = [{port, 8000},
{servername, "foobar"},
{listen, {127,0,0,1}},
{docroot, Docroot}],
{ok, SCList, GC, ChildSpecs} =
yaws_api:embedded_start_conf(Docroot, SconfList, GconfList, Id),
[supervisor:start_child(ybed_sup, Ch) || Ch <- ChildSpecs],
yaws_api:setconf(GC, SCList),
{ok, self()}.
当我编译它(成功)并尝试启动应用程序时,我得到一个返回值:
{error,{not_loaded,yaws}}
当我尝试运行已编译的ybed.erl时,ybed:run(),我得到:
** exception error: undefined function yaws_api:embedded_start_conf/4
in function ybed:run/0 (src/ybed.erl, line 16)
如果我在启动应用程序之前开始偏航,它仍然无法正常工作。
我还没有尝试构建版本,只是在嵌入模式下编译和测试偏航。谁能告诉我我失踪了什么?
提前致谢
答案 0 :(得分:0)
当您收到错误时
** exception error: undefined function yaws_api:embedded_start_conf/4
in function ybed:run/0 (src/ybed.erl, line 16)
您在code
server搜索路径中显然没有yaws_api.beam
。如果您不打算使用嵌入模式,请使用正确的erl
参数启动-pa
或在应用程序初始化中调用code:add_patha/1
。
BTW如何在yaws
文档中描述的自己的主管下启动yaws
,但是没有完整的代码,所以我们在这里进入一个模块,并提供整洁的调试资源和REST服务准备
-module(ybed_yaws).
-behaviour(supervisor).
-include_lib("yaws/include/yaws_api.hrl").
%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1]).
%% Internal functions export
-export([init_yaws/1, out/1]).
%%%===================================================================
%%% Defaults
%%%===================================================================
default_global() ->
#{id => "yaws", logdir => "log"}.
default_server() ->
#{port => 9900,
listen => {0,0,0,0},
docroot => "www",
appmods => [{"/", ?MODULE}]}.
%%%===================================================================
%%% API functions
%%%===================================================================
start_link() ->
supervisor:start_link(?MODULE, []).
%%%===================================================================
%%% Supervisor callbacks
%%%===================================================================
init([]) ->
{ok,
{{one_for_all, 0, 1},
[#{id => init_yaws,
start => {?MODULE, init_yaws, [self()]},
restart => transient}]
}}.
%%%===================================================================
%%% Internal functions
%%%===================================================================
init_yaws(Sup) ->
{ok, proc_lib:spawn_link(fun() -> config(Sup) end)}.
ensure_dir(Dir) ->
{ok, App} = application:get_application(),
D = filename:join([code:priv_dir(App), Dir])
filelib:ensure_dir(filename:join([D, "foo"])),
D.
config(Supervisor) ->
#{id := Id} = GCMap = default_global(),
#{docroot := DR} = SCMap = default_server(),
Docroot = ensure_dir(DR),
{ok, SC, GC, ChildSpecs} =
yaws_api:embedded_start_conf(
Docroot,
maps:to_list(SCMap#{docroot => Docroot}),
maps:to_list(GCMap),
Id),
[supervisor:start_child(Supervisor, Ch) || Ch <- ChildSpecs],
yaws_api:setconf(GC, SC),
ok.
-compile({inline, [h/1, f/2]}).
h(A) when is_atom(A) -> h(atom_to_binary(A, latin1));
h(S) -> yaws_api:htmlize(S).
f(Fmt, Args) -> yaws_api:f(Fmt, Args).
box(Str) ->
{'div',[{class,"box"}],
{pre, [], h(Str)}}.
out(A) ->
PathString = case A#arg.pathinfo of
undefined -> "";
P -> P
end,
Path = string:tokens(PathString, "/"),
Method = A#arg.req#http_request.method,
out(A, Method, Path).
out(A, Method, Path) ->
{ehtml,
{html, [],
[{head},
{body, [],
[
{h5, [], "Paths:"},
{hr},
box(f("Method = ~p~n"
"Path = ~p~n"
"A#arg.querydata = ~p~n",
[Method,
Path,
A#arg.querydata])),
{h5, [], "Headers:"},
{hr},
{ol, [], yaws_api:reformat_header(
A#arg.headers,
fun(H, V)->
{li, [], [h(H), ": ", {code, [], h(V)}]}
end
)}
]}
]}
}.
请注意在符合OTP的瞬态过程中yaws
初始化的方式,但没有gen_server
。
将{yaws, [{embedded, true}]}
添加到.config
文件,以使yaws
应用程序常用服务无法启动。它即使没有它也能工作,但它不会完全嵌入。