Elli与Elixir基本使用问题

时间:2015-10-21 14:56:55

标签: elixir

我在Elixir应用程序中使用elli https://github.com/knutin/elli

下面提供了示例代码。这是非常基本的,每次运行时,我只会得到“内部服务器错误”。我不确定我做错了什么。任何人都可以帮忙吗?

defmodule Client.TestHttp do
  @behaviour :elli_handler

  def handle(_Req,_Args) do
    handle(:elli_request.method(Req), :elli_request.path(Req),Args)
  end

  def handle_event(_,_,_)do
    :ok
  end

  def handle(:GET,[],_)do
    {:ok, [], "OkGet"}
  end
end

这就是我正在执行的方式

{:ok,pid}=:elli.start_link [callback: Client.TestHttp, port: 2020]

3 个答案:

答案 0 :(得分:4)

看起来您还没有完全翻译示例中的Erlang代码,并且仍在使用以大写字母开头的变量。

将句柄更改为:

  def handle(req, args) do
    handle(:elli_request.method(req), :elli_request.path(req), args)
  end

注意变量名称的区别。在Elixir中,变量用snake_caseCamelCase中的模块编写。在匹配中使用和加下(_)(例如_var)表示该变量未使用。

由于Elixir中的模块名称是原子,您的代码实际上会将ReqArgs扩展为原子:

Req == :'Elixir.Req' # true

答案 1 :(得分:1)

除了@ Gazier的回答(当然这是正确的),你的代码也会以另一种方式出错。在您的原始资料来源中:

def handle(_Req,_Args) do
    handle(:elli_request.method(Req), :elli_request.path(Req),Args)
end

调用:elli_request.method的参数需要为_Req,而:elli_request.path的参数也需要为_Req_Args。如果以大写字母开头的变量是正确的(它们不是),它将如下所示:

 def handle(_Req,_Args) do
        handle(:elli_request.method(_Req), :elli_request.path(_Req),_Args)
    end

但是,正如Gazier指出的那样,你的变量无论如何都没有正确设置。

答案 2 :(得分:0)

除了上面的答案,我想写一篇关于让knutin/elli与Elixir合作的完整指南。 上面的答案是正确的,但我需要更多的信息来启动和运行我的新elixir项目。

  1. 实施具有@behaviour :elli_handler

    的处理程序

    这是您的路由器/控制器。最简单的示例版本如下所示:

    # lib/elli_handler.ex
    defmodule ElliHandler do
      @behaviour :elli_handler
      alias :elli_request, as: Request
    
      def handle(req, args) do
        handle(Request.method(req), Request.path(req), req, args)
      end
    
      def handle(:GET, _, req, args) do
        # do something with the request.
        # e.g. you can use Request.get_arg/2 to fetch a query param
        say = Request.get_arg("say", req)
        # Return a tuple with 3 elements
        # status code, list of header tuples, response body
        {200, [], "echo, #{say}"}
      end
    
      # Here you can react to all kinds of events of the full connection/request/response cycle
      # You must implement this, otherwise elli wont function properly, as it evaluates
      # the return value of handle_event/3.
      def handle_event(event, args, config) do
        # Here would be a good point to handle logging.
        # IO.inspect([event, args, config])
        :ok
      end
    
    end
    
  2. 让我们使用启动elli主管的应用程序

    # lib/elli_supervisor.ex
    defmodule ElliSupervisor do
      use Supervisor
    
      def start_link(ref, options) do
        Supervisor.start_link(__MODULE__, options, name: ref)
      end
    
      def init(options) do
        children = [
          worker(:elli, [options], id: :elli_http_server)
        ]
        supervise(children, strategy: :one_for_one)
      end
    
      def shutdown(ref) do
        case Supervisor.terminate_child(ref, :elli_http_server) do
          :ok -> Supervisor.delete_child(ref, :elli_http_server)
          err -> err
        end
      end
    end
    
    # lib/app.ex
    defmodule App do
      use Application
    
      def start(_type, _args) do
        import Supervisor.Spec, warn: false
        # lets start our elli supervisor, setting its options
        # callback should be set to the elli handler that implements the elli_handler behaviour
        # port will be the port elli is listening on, defaults to 8080
        ElliSupervisor.start_link(__MODULE__, callback: ElliHandler, port: 3000)
      end
    
    end
    
    # in mix.exs
    def application do
      [
        mod: {App, []}
      ]
    end
    
  3. 将elli添加为mix.exs

    的依赖项

    运行mix get.deps以安装您的依赖项。 使用mix run --no-halt或使用iex -S mix在控制台中启动服务器。

    # in mix.exs
    defp deps do
      [
        # elli is our web server layer
        {:elli, github: "knutin/elli"}
      ]
    end