我在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]
答案 0 :(得分:4)
看起来您还没有完全翻译示例中的Erlang代码,并且仍在使用以大写字母开头的变量。
将句柄更改为:
def handle(req, args) do
handle(:elli_request.method(req), :elli_request.path(req), args)
end
注意变量名称的区别。在Elixir中,变量用snake_case
和CamelCase
中的模块编写。在匹配中使用和加下(_
)(例如_var
)表示该变量未使用。
由于Elixir中的模块名称是原子,您的代码实际上会将Req
和Args
扩展为原子:
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项目。
实施具有@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
让我们使用启动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
将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