问题
I was following along Programming Phoenix but using Elm for my front end, rather than Javascript. The second part of that book describes how to use websockets. The book's running example has you create an authentication token for the client side to pass to Phoenix at connection creation time. The Javascript Socket class provided with Phoenix allows that, but there's no obvious way to do it in Elm (as of 0.17 and the date of this question).
回答1:
As in the book, make the token visible to Javascript by attaching it to
window.<script>window.auth_token = "<%= assigns[:auth_token] %>"</script>In
web/static/js/app.js, you'll have code that starts Elm. Pass the token there.const c4uDiv = document.querySelector('#c4u-target'); if (c4uDiv) { Elm.C4u.embed(c4uDiv, {authToken: window.auth_token}); }- On the Elm side, you'll use
programWithFlagsinstead ofprogram. Your
initfunction will take a flags argument. (I'm using the Navigation library for a single-page app, which is why there's aPageChoiceargument as well.)type alias Flags = { authToken : String } init : Flags -> MyNav.PageChoice -> ( Model, Cmd Msg )Within
init, tack on the token as a URI query pair. Note that you have to uri-encode because the token contains odd characters. Here's the crude way to do that. Note: I am using the elm-phoenix-socket library below, but the same hackery would be required with others.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
回答2:
I got here by a Tweet by Brian, about encoding from Elm. In this case I like to handle it from the JavaScript side. I tried to replicate the way the Phoenix client sets it up. Instead of passing the token I passed the complete endpoint...
I've put the token in JSON a hash
<script id="app-json" type="application/json"><%= raw @json %></script>
Which I read on the client, and pass to the Elm embed
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
})
来源:https://stackoverflow.com/questions/40475348/how-do-i-pass-connection-time-websocket-parameters-to-phoenix-from-elm