簡體   English   中英

如何啟動偏航器以嵌入式模式運行?

[英]How do I start yaws to run in embedded mode?

我已經花了幾個小時嘗試使用yaws文檔和網絡搜索來解決此問題。 這里的現有線程對我沒有幫助。

我是erlang的新手,我正在嘗試使用http://yaws.hyber.org/embed.yaws上提供的示例代碼以嵌入式模式運行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)

如果在啟動應用程序之前先啟動偏航,它仍然不起作用。

我還沒有嘗試構建發行版,只是在嵌入式模式下編譯和測試了偏航。 誰能告訴我我所缺少的嗎?

提前致謝

當您遇到錯誤時

** exception error: undefined function yaws_api:embedded_start_conf/4
     in function  ybed:run/0 (src/ybed.erl, line 16)

您的code服務器搜索路徑中顯然沒有yaws_api.beam 如果您不打算使用嵌入式模式,請在應用程序初始化時使用適當的-pa參數或調用code:add_patha/1來啟動erl

順便說一句,有一種巧妙的方法可以在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應用程序常用服務啟動。 即使沒有它也可以工作,但不能完全嵌入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM