LiveBook 是 elixir 團隊新推出的一款應用,可以使用它很方便地在瀏覽器中編寫文章,並且在其中執行 elixir 程式碼。
我很好奇能否使用 LiveBook 直接更改當前伺服器的路由配置,使得我們可以實現實時部署服務。比如我們在 LiveBook 裡寫好一個頁面,然後直接配置到某個 url 路徑上,別人就可以訪問到。這樣感覺非常酷,省去了繁瑣的配置打包和釋出的流程,而且從理論上是完全可以實現的。
說幹就幹,首先我在 fly.io 上部署了一個免費的 livebook 例項,你也可以在本地部署,很方便的。
啟動之後在左側的配置按鈕裡選擇 Runtime settings
,選則 Embedded
。即在 livebook 本身的 erlang node 裡執行程式碼。livebook 為了保證安全性和隔離性,預設是會另啟動一個 node 來執行程式碼的,也就是 Elixir standalone
選項,但這樣我們是無法修改路由配置的。
修改好之後,我新建了一個文件,就可以開始寫程式碼了。Livebook 使用的是 Phoenix 框架,其底層的 HTTP 伺服器是 Cowboy,再底層是 ranch。所以我們先通過 :ranch.info()
來獲取當前伺服器的一些資訊。從返回值裡我們知道了當前的 ranch server 的ref是 LivebookWeb.Endpoint.HTTP
,所有的路由(或者叫分發 Dispatch) 配置都是在這裡面儲存。下一步我們就可以對 dispatch 配置進行修改。
每個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)
試著訪問一下我們配置的路徑。成功了!