LiveBook 是 elixir 团队新推出的一款应用,可以使用它很方便地在浏览器中编写文章,并且在其中运行 elixir 代码。

我很好奇能否使用 LiveBook 直接更改当前服务器的路由配置,使得我们可以实现实时部署服务。比如我们在 LiveBook 里写好一个页面,然后直接配置到某个 url 路径上,别人就可以访问到。这样感觉非常酷,省去了繁琐的配置打包和发布的流程,而且从理论上是完全可以实现的。

说干就干,首先我在 fly.io 上部署了一个免费的 livebook 实例,你也可以在本地部署,很方便的。

启动之后在左侧的配置按钮里选择 Runtime settings,选则 Embedded。即在 livebook 本身的 erlang node 里执行代码。livebook 为了保证安全性和隔离性,默认是会另启动一个 node 来执行代码的,也就是 Elixir standalone 选项,但这样我们是无法修改路由配置的。

image.png

修改好之后,我新建了一个文档,就可以开始写代码了。Livebook 使用的是 Phoenix 框架,其底层的 HTTP 服务器是 Cowboy,再底层是 ranch。所以我们先通过 :ranch.info() 来获取当前服务器的一些信息。从返回值里我们知道了当前的 ranch server 的ref是 LivebookWeb.Endpoint.HTTP,所有的路由(或者叫分发 Dispatch) 配置都是在这里面保存。下一步我们就可以对 dispatch 配置进行修改。

image.png

每个http请求都会被分发到不同的 handler(这个怎么翻译来着,抓手?),所以我们首先需要写一个用于测试的 handler。

defmodule TestHandler do
  @behaviour :cowboy_handler

  def init(req, state) do
    req = :cowboy_req.reply(200, %{
        "content-type" => "text/plain"
    }, "Hello World!", req)
    {:ok, req, state}
  end
end

它的功能非常简单,无论收到什么都返回你好世界。接下来将它配置到我们的 dispatch 里面,注意要保留之前的 dispatch 内容,否则我们的 livebook 就访问不了了哈哈。

dispatch = :cowboy_router.compile([{:_, [], [
  {'/test', [], TestHandler, %{}},
  {:_, [], Phoenix.Endpoint.Cowboy2Handler, {LivebookWeb.Endpoint, []}}
]}])

最后使用 cowboy 提供的实时更新功能,将新的配置部署到我们的 ranch server 里面:

:cowboy.set_env(LivebookWeb.Endpoint.HTTP, :dispatch, dispatch)

试着访问一下我们配置的路径。成功了!
image.png


Ljzn
399 声望102 粉丝

网络安全;函数式编程;数字货币;人工智能