[英]How do I start yaws to run in embedded mode?
I've spent several hours trying to troubleshoot this issue using the yaws documentation and web searches. 我已经花了几个小时尝试使用yaws文档和网络搜索来解决此问题。 The existing threads here haven't helped me. 这里的现有线程对我没有帮助。
I am new to erlang and I am trying to run yaws in embedded mode using the sample code provided on http://yaws.hyber.org/embed.yaws . 我是erlang的新手,我正在尝试使用http://yaws.hyber.org/embed.yaws上提供的示例代码以嵌入式模式运行yaws。 I am missing something because I cannot get it to work. 我错过了一些东西,因为我无法使它正常工作。 I have four files: 我有四个文件:
ybed.app 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 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 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 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()}.
When I compile it (successfully) and try to start the application, I get a return value: 当我成功编译它并尝试启动该应用程序时,我得到一个返回值:
{error,{not_loaded,yaws}}
When I try to run the compiled ybed.erl, ybed:run(), I get: 当我尝试运行已编译的ybed.erl ybed:run()时,我得到:
** exception error: undefined function yaws_api:embedded_start_conf/4
in function ybed:run/0 (src/ybed.erl, line 16)
If I start yaws before I start the application, it still doesn't work. 如果在启动应用程序之前先启动偏航,它仍然不起作用。
I am not trying to build releases yet, just compile and test yaws in embedded mode. 我还没有尝试构建发行版,只是在嵌入式模式下编译和测试了偏航。 Can anyone tell me what I'm missing? 谁能告诉我我所缺少的吗?
Thanks in advance 提前致谢
When you get error 当您遇到错误时
** exception error: undefined function yaws_api:embedded_start_conf/4
in function ybed:run/0 (src/ybed.erl, line 16)
You clearly don't have yaws_api.beam
in your code
server search path. 您的code
服务器搜索路径中显然没有yaws_api.beam
。 Start your erl
with proper -pa
argument or call code:add_patha/1
in your application initialization if you are not planning use embedded mode. 如果您不打算使用嵌入式模式,请在应用程序初始化时使用适当的-pa
参数或调用code:add_patha/1
来启动erl
。
BTW there is a neat way how to start yaws
under your own supervisor described in yaws
documentation but without complete code so here we go in one module and with neat debugging resource and preparation for REST servicing. 顺便说一句,有一种巧妙的方法可以在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
)}
]}
]}
}.
Note the way how is yaws
initialised in OTP compliant transient process but without gen_server
. 请注意如何在OTP兼容的瞬态过程中初始化yaws
,但没有gen_server
。
Add {yaws, [{embedded, true}]}
to your .config
file to keep yaws
application common services from starting. 将{yaws, [{embedded, true}]}
到您的.config
文件中,以防止yaws
应用程序常用服务启动。 It will work even without it but it will not be fully embedded. 即使没有它也可以工作,但不能完全嵌入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.