0

我正在尝试这个 github 存储库提供的牛仔示例:

https://github.com/ninenines/cowboy/tree/master/examples/web_server

我使用 erlang.mk 成功构建了版本并运行以下命令,这将在我的 linux 终端中打开 Erlang shell:

$ ./_rel/web_server_example/bin/web_server_example console

但是当我 http://localhost:8080在我的网络浏览器中打开时,我收到以下错误报告:

=错误报告==== 2014 年 11 月 26 日::14:33:48 === 节点“web_server_example@127.0.0.1”上的进程 <0.166.0> 出错,退出值:{function_clause,[{cowboy_req, ensure_response,[{ok,{http_req,#Port<0.454>,ranch_tcp,keepalive,<0.166.0>,<<3 bytes>>,'HTTP/1.1',{{127,0,0,1},57150 },<<9 字节>>,未定义,8080,<<1 字节>>,未定义,<<0 字节>>,未定义,未定义,[{<<4 字节>>,<<14 字节>>}, {<<10 字节>>,<<10 字节>>},{<<13 字节>>,<<9 字节>>},{<<6 字节>>,<<74 字节>>},{< <10 字节>>,<<104 字节>>},{<<15 字节>>,<<19 字节>>},{<<15 字节>>,<<35 字节>>}],[{< <10 字节>>,[<<10 字节>>]}],未定义,[],等待,<<0 字节>>,未定义...

=错误报告==== 2014 年 11 月 26 日::14:33:48 === 牧场侦听器 http 在 <0.166.0> 退出时使用 cowboy_protocol:start_link/4 启动了连接过程,原因是:{function_clause,[{ cowboy_req,ensure_response,[{ok,{http_req,#Port<0.454>,ranch_tcp,keepalive,<0.166.0>,<<"GET">>,'HTTP/1.1',{{127,0,0,1 },57150},<<"localhost">>,undefined,8080,<<"/">>,undefined,<<>>,undefined,undefined,[{<<"host">>,<<"localhost :8080">>},{<<"connection">>,<<"keep-alive">>},{<<"cache-control">>,<<"max-age=0">>} ,{<<"接受">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8">>},{<<"user-agent">>,<<"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36" >>},{<<"accept-encoding">>,<<"gzip, deflate, sdch">>},{<<"accept-language">>,<<"sv-SE,sv;q= 0.8,en-US;q=0.6,en;q=0.4">>}],[{<<"connection">>,[<<"keep-alive">>]}],undefined,[],等待,<<>>,undefined,false,done,[],<<>>,undefined}},204],[{file,"src/cowboy_req.erl"},{line,1009}]},{ cowboy_protocol,next_request,3,[{file,"src/cowboy_protocol.erl"},{line,454}]}]}

这是第 454 行附近的“src/cowboy_protocol.erl”:

-spec next_request(cowboy_req:req(), #state{}, any()) -> ok.
next_request(Req, State=#state{req_keepalive=Keepalive, timeout=Timeout},
        HandlerRes) ->
    cowboy_req:ensure_response(Req, 204),
    %% If we are going to close the connection,
    %% we do not want to attempt to skip the body.
    case cowboy_req:get(connection, Req) of
        close ->
            terminate(State);
        _ ->
            %% Skip the body if it is reasonably sized. Close otherwise.
            Buffer = case cowboy_req:body(Req) of
                {ok, _, Req2} -> cowboy_req:get(buffer, Req2);
                _ -> close
            end,
            %% Flush the resp_sent message before moving on.
            if HandlerRes =:= ok, Buffer =/= close ->
                    receive {cowboy_req, resp_sent} -> ok after 0 -> ok end,
                    ?MODULE:parse_request(Buffer,
                        State#state{req_keepalive=Keepalive + 1,
                        until=until(Timeout)}, 0);
                true ->
                    terminate(State)
            end
    end.

和 webb_server_app.erl 文件:

%% Feel free to use, reuse and abuse the code in this file.

%% @private
-module(web_server_app).
-behaviour(application).

%% API.
-export([start/2]).
-export([stop/1]).

%% API.

start(_Type, _Args) ->
    Dispatch = cowboy_router:compile([
        {'_', [
            {"/[...]", cowboy_static, {priv_dir, web_server, "", [
                {mimetypes, cow_mimetypes, all},
                {dir_handler, directory_handler}
            ]}}
        ]}
    ]),
    {ok, _} = cowboy:start_http(http, 100, [{port, 8080}], [
        {env, [{dispatch, Dispatch}]},
        {middlewares, [cowboy_router, directory_lister, cowboy_handler]}
    ]),
    web_server_sup:start_link().

stop(_State) ->
    ok.

有没有人对究竟是什么导致这个问题以及如何解决它有任何建议?谢谢。

编辑:

我可以确认故障出在 Erlang OTP 版本 R16B02 中。更改为最新的 Erlang 版本 (17.3),以及解决在配置阶段出现的缺失文件依赖项(使用以下链接中的解决方案):

https://sites.google.com/site/comptekkia/erlang/how-to-install-erlang-on-ubuntu-10-10

解决了问题。web_server 示例现在可以正常运行。

4

1 回答 1

1

错误说function clause,所以参数cowboy_req:ensure_response/2必须是错误的。确实如此,因为第一个论点{ok, Request}不是Request. 您必须追溯next_request/3使用错误参数调用哪个函数,因为它显然应该在没有ok.

可能在最后的某个地方,你会发现类似的东西:

Req = some_function(...)

您需要将其更改为:

{ok, Req} = some_function(...)

祝你好运和快乐的错误狩猎:D

更新:我刚刚克隆了 repo,它对我来说很好。我得到了目录列表,所以它不是牛仔中的错误,而是用户代码中的某个地方。

于 2014-11-26T15:16:35.200 回答