使用 Phoenix LiveBook 做一個小實驗 ---- 實時編碼+部署http服務

Ljzn發表於2022-06-13

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

相關文章