【问题标题】:How do I pass connection-time websocket parameters to Phoenix from Elm?如何从 Elm 将连接时 websocket 参数传递给 Phoenix?
【发布时间】:2017-03-21 09:31:23
【问题描述】:
我一直在关注 Programming Phoenix,但我的前端使用 Elm,而不是 Javascript。该书的第二部分描述了如何使用 websockets。本书的运行示例让您为客户端创建一个身份验证令牌,以便在创建连接时传递给 Phoenix。 Phoenix 提供的 Javascript Socket 类允许这样做,但在 Elm 中没有明显的方法可以做到这一点(截至 0.17 和这个问题的日期)。
【问题讨论】:
标签:
websocket
phoenix-framework
elm
【解决方案1】:
我是通过 Brian 的一条关于 Elm 编码的推文来到这里的。
在这种情况下,我喜欢从 JavaScript 端处理它。
我试图复制 Phoenix 客户端的设置方式。
我没有传递令牌,而是传递了完整的端点......
我已将令牌放入 JSON 中的哈希
<script id="app-json" type="application/json"><%= raw @json %></script>
我在客户端上阅读并传递给 Elm 嵌入
var data = JSON.parse(document.getElementById("app-json").innerHTML)
var token = encodeURIComponent(data.token)
var elm = window.Elm.App.embed(document.getElementById("elm-container"), {
socketEndpoint: "ws://" + window.location.host + "/socket/websocket?token=" + token
})
【解决方案2】:
-
如书中所述,通过将令牌附加到 window 使 Javascript 可见。
<script>window.auth_token = "<%= assigns[:auth_token] %>"</script>
-
在web/static/js/app.js 中,您将拥有启动 Elm 的代码。在那里传递令牌。
const c4uDiv = document.querySelector('#c4u-target');
if (c4uDiv) {
Elm.C4u.embed(c4uDiv, {authToken: window.auth_token});
}
- 在 Elm 方面,您将使用
programWithFlags 而不是 program。
-
您的init 函数将采用标志参数。 (我将Navigation 库用于单页应用程序,这就是为什么还有PageChoice 参数。)
type alias Flags =
{ authToken : String
}
init : Flags -> MyNav.PageChoice -> ( Model, Cmd Msg )
-
在init 内,将令牌添加为 URI 查询对。请注意,您必须进行 uri 编码,因为令牌包含奇数字符。这是执行此操作的粗略方法。注意:我正在使用下面的elm-phoenix-socket 库,但其他人需要相同的hackery。
let
uri = "ws://localhost:4000/socket/websocket?auth_token=" ++
(Http.uriEncode flags.authToken)
in
uri
|> Phoenix.Socket.init
|> Phoenix.Socket.withDebug
|> Phoenix.Socket.on "ping" "c4u" ReceiveMessage